Я уже некоторое время сталкиваюсь с этой проблемой, но до сих пор не понял. Я не программист, я инженер, который немного разбирается в кодировании, поэтому будьте осторожны.
Я пишу пользовательские функции для 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