0

我已经遇到这个问题一段时间了,我还没有弄清楚。我不是程序员,我是一名对编码略知一二的工程师,所以请保持温和。

我正在为 MathCAD Prime 编写自定义函数,并使用了软件提供的示例。我已经成功地编写了 C++ 代码并将其编译为 DLL 以供软件使用;但是,当我尝试在 Windows 中使用 Math.h 库标准中的余弦、正弦等函数时,我收到了一个 LNK2019 错误,可以在下面找到。

仅当我使用在任何(推测)附加 .h 库头文件中找到的函数时才会发生这种情况,这些函数不是为创建自定义函数而提供的目标软件 (MathCAD) 头文件的一部分。

有人可以帮我成功编译一个使用 Math.h 库及其函数的 DLL 吗?

我已经从 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 }
};

这是我尝试编译时遇到的链接器错误...

函数“__int64 __cdecl RotateZFunc(struct tagCOMPLEXARRAY * const,struct tagCOMPLEXSCALAR const * const)”中引用的错误 LNK2019 未解析的外部符号 cos (?RotateZFunc@@YA_JQEAUtagCOMPLEXARRAY@@QEBUtagCOMPLEXSCALAR@@@Z) amjCustomFunctions ...\RotateZ.obj 1

函数“__int64 __cdecl RotateZFunc(struct tagCOMPLEXARRAY * const,struct tagCOMPLEXSCALAR const * const)”中引用的错误 LNK2019 未解析的外部符号 sin (?RotateZFunc@@YA_JQEAUtagCOMPLEXARRAY@@QEBUtagCOMPLEXSCALAR@@@Z) amjCustomFunctions ...\RotateZ.obj 1

4

0 回答 0