【问题标题】:Link to a DLL in Pelles C链接到 Pelles C 中的 DLL
【发布时间】:2016-10-27 10:41:11
【问题描述】:

我有一个 218KB .dll 和一个 596KB .so 文件,两者的名称相同。我想链接到.dll以避免链接器返回的“未解析的外部符号”错误,但是我找不到链接到DLL文件的方法。

根据this Pelles C forum topic,我需要使用.def文件来创建.lib...但是我没有.def文件。 This forum topic 展示了如何使用polink 从命令行创建.lib,所以我运行polink /? 以获得更多选项。我注意到一个/MAKEDEF 选项,但同时使用.dll.so 运行此选项会出现“未指定库文件”的致命错误。

我已经尝试了三个小时,但没有任何想法。我已经到了我的网络搜索出现我自己的帮助请求的地步。一定有办法做到这一点...我怎样才能链接到.dll

【问题讨论】:

  • 如果您既没有.lib(导入库)也没有.def(导出定义),您至少需要知道导出了哪些函数(供外部软件使用)。但是,即使您可以从 .dll 生成 .lib 或 .def,您也不能使用没有定义标头(C 中的 .h)的 .dll,其中所有导出的函数都已完全描述(名称、参数类型、结果类型) ...和调用约定),您将无法使用 .dll。
  • @J.Piquard 我有头文件。只是链接器不起作用。
  • 在编译你的c源代码时,你添加了这个头文件吗?如果有,你得到了什么样的“未解析的外部符号”?
  • @J.Piquard POLINK:错误:未解析的外部符号“__imp_XPLMRegisterFlightLoopCallback”。
  • 你在使用这个标题#include <XPLM/XPLMProcessing.h>,你是否尝试使用像XPLMRegisterFlightLoopCallback()这样的功能?

标签: c dll shared-libraries pelles-c


【解决方案1】:

根据标题#include 中的信息和您的详细信息,这是一种通过从您的软件中动态调用它们来替换缺失函数的方法。 1- 以下原型在#include 中:

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

2- 一些你可以根据需要填写的常量:

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

为了确认sXPLMRegisterFlightLoopCallbackName,您可以 使用免费软件Dependency Walker 并检查名称和格式 导出的函数。

3-声明外部函数的原型:

注意调用约定__cdecl__stdcall

在当前情况下,关键字XPLM_APIXPLMDefs.h中定义如下:

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

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

4- 克隆函数以在您的软件中调用它:

#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- 只需添加您描述的调用:

...
XPLMRegisterFlightLoopCallback(callbackfunction, 0, NULL);
...

【讨论】:

  • 如果 DLL 是从 另一个 DLL 加载的,这会起作用吗?
  • 使用 LoadLibrary 不会检查 DLL 是否仍然从另一个加载。您能否添加有关该其他 DLL 的一些详细信息?你在同一个软件中使用过吗?
  • 我才意识到我的 cmets 是多么的模棱两可。我正在编写一个插件,它是一个 DLL。同一程序可能还导入了其他 DLL 插件。文档说要链接到 DLL,而不是直接加载它,所以我问它在这种情况下是否仍然有效。
  • 您发送到 XPLMRegisterFlightLoopCallback()(插件或主软件)的 callbackfunction 来自哪里?但我认为这不会是一个真正的问题,因为 DLL 封装不需要本地资源。
  • 来自插件。谢谢你的帮助;如果这可行,您肯定会得到绿色复选标记! :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
  • 1970-01-01
相关资源
最近更新 更多