ошибка LNK2019: неразрешенный внешний символ из-за ссылки в функции - PullRequest
0 голосов
/ 30 сентября 2019

Я уже некоторое время сталкиваюсь с этой проблемой, но до сих пор не понял. Я не программист, я инженер, который немного разбирается в кодировании, поэтому будьте осторожны.

Я пишу пользовательские функции для MathCAD Prime и использовал примеры, поставляемые с программным обеспечением. Я успешно написал код C ++ и скомпилировал его в DLL для использования с программным обеспечением;однако, когда я пытаюсь использовать такие функции, как косинус, синус и т. д. из стандарта библиотеки Math.h в Windows, я получаю сообщение об ошибке LNK2019, которое можно найти ниже.

Это происходит только при использованиифункции, найденные в любом (спекулятивном) дополнительном заголовке библиотеки .h, который не является частью заголовочного файла целевого программного обеспечения (MathCAD), предоставленного для создания пользовательских функций.

Может кто-нибудь, пожалуйста, помогите мне успешно скомпилировать DLL, которая используетбиблиотека Math.h и ее функции?

Я уже искал руководство на форумах здесь, посвященном StackOverflow, и до сих пор не смог найти решение в моей конкретной области проблемы.

//This is the dllmain.cpp that is attaching the custom functions to MathCAD when it opens.
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

// ***********************************************************************
// This source CPP is used to establish the entry points for all functions
// compiled into the DLL. This is critical to the successful functionality
// of the custom functions inside of MathCAD.
// ***********************************************************************

// Add function name to this list of declared external variables.
// This name should be the same name used to define the function
// in the CPP. You will need to include the same name into the 
// DllEntryPoint function below in order to successfully build.
extern FUNCTIONINFO RotateZ;


// Table of error messages if your function never returns an error -- you do not need to create this table
char * myErrorMessageTable[NUMBER_OF_ERRORS] = { "interrupted",
                                                 "insufficient memory",
                                                 "must be real",
                                                 "must be an integer GTE 0" };

// Needed if compiling to a 32-bit machine.
//BOOL WINAPI _CRT_INIT(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved);

// DllEntryPoint function used to compile the listed functions into the DLL.
BOOL WINAPI DllEntryPoint(HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        // DLL is attaching to the address space of the current process.
        // Needed if compiling to a 32-bit machine.
        //if (!_CRT_INIT(hDLL, dwReason, lpReserved)) { return FALSE; } 

        // Creating error message table...
        if (!CreateUserErrorMessageTable(hDLL, NUMBER_OF_ERRORS, myErrorMessageTable))  break;

        // Creating each function and referencing the function location in the CPP.
        if (CreateUserFunction(hDLL, &RotateZ) == NULL) { break; }

    }
    case DLL_THREAD_ATTACH:       // A new thread is being created in the current process.
    case DLL_THREAD_DETACH:       // A thread is exiting cleanly.
    case DLL_PROCESS_DETACH:      // The calling process is detaching the DLL from its address space.
    {
        // Needed if compiling to a 32-bit machine.
        //if (!_CRT_INIT(hDLL, dwReason, lpReserved)) { return FALSE; }
        break;
    }
    }
    return TRUE;
}



BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}




//stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
//
#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
#include <math.h>
//#include <cmath>
//#include <iostream>
//#include <string>

// reference additional headers your program requires here

#include "MCADINCL.h"

using namespace std;

constexpr auto SUCCESS = 0;

constexpr auto INTERRUPTED = 1;
constexpr auto INSUFFICIENT_MEMORY = 2;
constexpr auto MUST_BE_REAL = 3;
constexpr auto MUST_BE_INT_GT_ZERO = 4;

constexpr auto NUMBER_OF_ERRORS = 4;



//RotateX.cpp
#include <stdafx.h> // <math.h> is included in stdafx.h

// this code executes the multiplication see the information of MathcadUserFunction to find out more.
LRESULT  RotateZFunc(COMPLEXARRAY * const ResultArray, LPCCOMPLEXSCALAR theta)
{

    // Setting the number of rows and cols for the ResultArray.
    unsigned int nRows = 3;
    unsigned int nCols = 3;

    // Checking for real and imaginary parts of the incoming
    // array argument.
    bool allocateRealMem = (theta->real != NULL);
    bool allocateImagMem = (theta->imag != NULL);
    if (allocateImagMem) { return MAKELRESULT(MUST_BE_REAL, 1); }

    if (!MathcadArrayAllocate
    (
        ResultArray, // Allocate memory for the ResultArray
        nRows, // Specifying number of rows
        nCols,  // Specifying number of columns
        allocateRealMem, // Allocate memory for the real part
        allocateImagMem // Allocate memory for the imaginary part
    )
        )
        // if allocation is not successful return with the appropriate error code
    {
        return  INSUFFICIENT_MEMORY;
    }

    // check that a user has not tried to interrupt the calculation
    if (isUserInterrupted())
    {
        // if user has interrupted -- free the allocated memory
        MathcadArrayFree(ResultArray);
        // and return with an appropriate error code
        return INTERRUPTED;
    }


    if (allocateRealMem)
    {
        ResultArray->hReal[0][0] = cos(theta->real); // double __cdecl cos(double _X)
        ResultArray->hReal[0][1] = sin(theta->real); // double __cdecl sin(double _X)
        ResultArray->hReal[0][2] = 0;
        ResultArray->hReal[1][0] = -sin(theta->real); // double __cdecl sin(double _X)
        ResultArray->hReal[1][1] = cos(theta->real); // double __cdecl cos(double _X)
        ResultArray->hReal[1][2] = 0;
        ResultArray->hReal[2][0] = 0;
        ResultArray->hReal[2][1] = 0;
        ResultArray->hReal[2][2] = 1;
    }

    return SUCCESS; // Normal Return
}

// fill out a FUNCTIONINFO structure with the information needed for registering the function with Mathcad
FUNCTIONINFO RotateZ =
{
    // Name by which mathcad will recognize the function
    "Rz",

    // description of "RotateZ" parameters to be used
    // by the Insert Function dialog box
    "theta",

    // description of the function for the Insert Function dialog box
    "returns the rotation matrix by theta",

    // pointer to the executable code i.e. code that should be executed when a user types in "RotateZ(theta)="
    (LPCFUNCTION)RotateXFunc,

    // RotateZ(theta) returns a complex array
    COMPLEX_ARRAY,

    // RotateZ(theta) takes on one argument
    1,

    // the first is a complex scalar 
    { COMPLEX_SCALAR }
};

Это ошибка компоновщика, которую я получаю, когда пытаюсь скомпилировать ...

Ошибка LNK2019: неразрешенный внешний символ из-за ссылки в функции "__int64 __cdecl RotateZFunc (struct tagCOMPLEXARRAY * const, struct tagCOMPLEXSCALAR const * const)"(? RotateZFunc @@ YA_JQEAUtagCOMPLEXARRAY @@ QEBUtagCOMPLEXSCALAR @@@ Z) amjCustomFunctions ... \ RotateZ.obj 1

Ошибка LNK2019: неразрешенный внешний символ sin, на который ссылается функция "__int64 __cdecl RotateZFunc (struct tagCOMPLEXARRAY * const, struct tagCOMPLEXSCALAR const * const)"? @@@ Z) amjCustomFunctions ... \ RotateZ.obj 1

...