0

I have been experiencing this issue for a while and I have not figured it out. I am not a programmer, I am an engineer that knows a little about coding so please be gentle.

I am writing custom functions for MathCAD Prime and have used the examples provided with the software. I have been successful in writing C++ code and compiling it into a DLL for use with the software; however, when I try and use functions like cosine, sine, etc. from the Math.h library standard in Windows, I am getting a LNK2019 error which can be found below.

This only occurs when I am using the functions found in any (speculation) additional .h library header that is not apart of the target software's (MathCAD) header file provided to create the custom functions.

Can someone please help me successfully compile a DLL that uses the Math.h library and the functions therein?

I have already sought out guidance from the forums here on StackOverflow and have so far been unable to find a solution in my specific problem scope.

//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 }
};

This is the linker error I am getting when I try and compile...

Error LNK2019 unresolved external symbol cos referenced in function "__int64 __cdecl RotateZFunc(struct tagCOMPLEXARRAY * const,struct tagCOMPLEXSCALAR const * const)" (?RotateZFunc@@YA_JQEAUtagCOMPLEXARRAY@@QEBUtagCOMPLEXSCALAR@@@Z) amjCustomFunctions ...\RotateZ.obj 1

Error LNK2019 unresolved external symbol sin referenced in function "__int64 __cdecl RotateZFunc(struct tagCOMPLEXARRAY * const,struct tagCOMPLEXSCALAR const * const)" (?RotateZFunc@@YA_JQEAUtagCOMPLEXARRAY@@QEBUtagCOMPLEXSCALAR@@@Z) amjCustomFunctions ...\RotateZ.obj 1

amorenojr
  • 21
  • 3
  • 2
    Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Sep 30 '19 at 02:06
  • I have repeatedly looked at that link but find it contains a fair amount of noise and doesn't specifically address my issue. The math.h library is standard in Windows, and the libraries that are included in the project include the standard Windows library directories. I don't really know what I am doing but have felt my way through this problem up until this point. I need a good push across the finish. – amorenojr Oct 03 '19 at 22:22
  • It's impossible to write a separate answer for every possible library specifically that might cause this error. The vast majority of times the linked duplicate provides sufficient information to use to solve the problem. There are also others here that you can find by searching for the specific symbol contained in the error message. – Ken White Oct 03 '19 at 22:29

0 Answers0