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