1

I have a 218KB .dll and a 596KB .so file, both with identical names. I want to link to the .dll to avoid the "unresolved external symbol" error that the linker returns, but I can't find a way to link to the DLL file.

According to this Pelles C forum topic, I need to use the .def file to create a .lib... but I don't have a .def file. This forum topic shows how to use polink to create a .lib from the command line, so I ran polink /? to get some more options. I noticed a /MAKEDEF option, but running this with both the .dll and the .so gives a "No library file specified" fatal error.

I have been trying to do this for three hours, and am out of ideas. I have got to the point where my web searches turn up my own help-requests. There must be a way to do this... How can I link to a .dll?

wizzwizz4
  • 6,140
  • 2
  • 26
  • 62
  • If you have neither .lib (import library) nor .def (exported definition), you need to know at least which functions are exported (to be used by an external software). But even if you can generate a .lib or .def from your .dll, you can't use the .dll without a definition header (.h in C) where all exported functions are fully described (name, parameters type, result type ... and calling convention), you will be not able to use the .dll. – J. Piquard Oct 27 '16 at 11:42
  • @J.Piquard I have the header file. It's just the linker that doesn't work. – wizzwizz4 Oct 27 '16 at 14:29
  • when compiling your c source code, did you add this header ? If so, what kind of "unresolved external symbol" did you obtain ? – J. Piquard Oct 27 '16 at 15:52
  • @J.Piquard **POLINK: error: Unresolved external symbol '__imp_XPLMRegisterFlightLoopCallback'.** – wizzwizz4 Oct 27 '16 at 19:10
  • Are you using this header `#include ` and do you try to use function like `XPLMRegisterFlightLoopCallback()` ? – J. Piquard Oct 27 '16 at 19:29
  • @J.Piquard I am using the header with `""` and full relative path, calling the function with required parameters, i.e. `XPLMRegisterFlightLoopCallback(callbackfunction, 0, NULL);`. I am confident that this is correct, because when it isn't different errors are thrown. I appreciate your help, and hope to upvote your answer if you can find it. :-) – wizzwizz4 Oct 27 '16 at 20:25

1 Answers1

1

With information found in the header #include and your details, here is a way to replace the missing function by calling them dynamically from your software. 1- the following prototype is in #include :

typedef float (* XPLMFlightLoop_f)(float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon);

2- some const that you can fill as needed:

const char *sDllPathName = "<Your XPLM_API DLL>.dll";
const char *sXPLMRegisterFlightLoopCallbackName = "XPLMRegisterFlightLoopCallback";

In order to confirm the sXPLMRegisterFlightLoopCallbackName, you can use the freeware Dependency Walker and check name and format of the exported functions.

3- declare the prototype of the external function:

Be aware to the calling convention __cdecl or __stdcall

In the current case, the keyword XPLM_API is defined in the XPLMDefs.h as follow:

#define XPLM_API __declspec(dllexport) // meaning __cdecl calling convention

typedef void (__cdecl *XPLMRegisterFlightLoopCallback_PROC)(XPLMFlightLoop_f, float, void *);

4- clone the function to call it in your software:

#include <windows.h>

void XPLMRegisterFlightLoopCallback(XPLMFlightLoop_f inFlightLoop, float inInterval, void * inRefcon)
{
    HINSTANCE hInstDLL;
    XPLMRegisterFlightLoopCallback_PROC pMyDynamicProc = NULL;

    // Load your DLL in memory
    hInstDLL = LoadLibrary(sDllPathName);
    if (hInstDLL!=NULL)
    {
        // Search for the XPLM Function
        pMyDynamicProc = (XPLMRegisterFlightLoopCallback_PROC) GetProcAddress(hInstDLL, sXPLMRegisterFlightLoopCallbackName);
        if (pMyDynamicProc != NULL)
        {
            // Call the XPLM Function with the orignal parameter
            (pMyDynamicProc)(inFlightLoop,inInterval,inRefcon);
            return;
        }
    }
    // Do something when DLL is missing or function not found
}

5- just add your described call:

...
XPLMRegisterFlightLoopCallback(callbackfunction, 0, NULL);
...
J. Piquard
  • 1,665
  • 2
  • 12
  • 17
  • Would this work if the DLL was being loaded from *another DLL*? – wizzwizz4 Oct 28 '16 at 08:49
  • The use of LoadLibrary doesn't check if the DLL has been still loaded from another. Could you add some details about that other DLL ? Did you use it in the same software ? – J. Piquard Oct 28 '16 at 09:00
  • I just realised how ambiguous my comments was. I am writing a plugin, which is a DLL. There may be other DLL plugins imported by the same program. The documentation says to link to the DLL, not to directly load it, so I was asking whether it would still work in that case. – wizzwizz4 Oct 28 '16 at 09:10
  • Where come from the `callbackfunction` that you are sending to XPLMRegisterFlightLoopCallback() (plugin or main software) ? But I think it will be not a real problem because the DLL encapsulation doesn't needed local resources. – J. Piquard Oct 28 '16 at 09:52
  • It comes from the plugin. Thanks for your help; if this works you'll definitely get the green checkmark! :-) – wizzwizz4 Oct 28 '16 at 10:11
  • In order to confirm the `sXPLMRegisterFlightLoopCallbackName`, you can use the freeware [Dependency Walker](http://www.dependencywalker.com/) and check the format of the exported functions. – J. Piquard Oct 28 '16 at 10:25
  • Could I use Dependency Walker to just get the `.def` file outright? – wizzwizz4 Oct 28 '16 at 10:54
  • @wizzwizz4 this is not the job of Dependency Walker. But it is possible to generate a dependency list text file. – J. Piquard Oct 28 '16 at 11:15
  • I couldn't reach the Dependency Walker website but I downloaded the program from archive.org and it works really well. Just in case I need to use it, where's the "generate text file" button? – wizzwizz4 Oct 28 '16 at 11:25
  • Also, does a `[C ]` icon mean `__cdecl`? (Just found the help topic; where can I find the `__cdecl` / `__stdcall` distinguisherer?) – wizzwizz4 Oct 28 '16 at 11:27
  • with depends, go to Save As and select text file. The meaning of `[C ]` is only Function !!! – J. Piquard Oct 28 '16 at 11:36
  • In the `XPLMDefs.h` the export attribute is defined as `#define XPLM_API __declspec(dllexport)`. So it is certainly `__cdecl`. – J. Piquard Oct 28 '16 at 11:46
  • :facepalm: Thanks! (I *thought* I was good at C...) I think you should add the "check function names in DLL using Dependency Walker" to the answer, just to help future people. – wizzwizz4 Oct 28 '16 at 11:48