c++ - 我怎样才能在运行时像可执行文件一样 "start"DLL?

标签 c++ dll loadlibrary getprocaddress

我想编写一个非常非常小的程序来解析启动参数并选择几个 DLL 之一“启动”。

我已经编写了一个应用程序,我希望将其作为 DLL“运行”,方法是将其编写为应用程序,然后更改 Visual Studio 项目属性以将其构建为 DLL。我知道我需要同时使用 LoadLibrary 和 GetProcAddress 来获得我想要的功能,但我很难找到关于此的清晰而全面的文档,因为很多用例并不是真正的这种性质。另外,我必须根据项目和平台限制走这条路。

我找到了 this page ,其中有一些信息,但不够清晰,无法根据我的目的进行调整。

编辑:这是我现在所在的位置。

我有一个 DLL 项目,其主要函数签名如下所示:

__declspec(dllexport) int cdecl main(int argc, char *argv[])

我还有一个应用程序项目,它尝试加载 DLL 并运行上述函数,如下所示:

typedef int (CALLBACK* LPFNDLLFUNC1)(int, char *);

...

        HMODULE dllHandle = NULL;
        BOOL freeResult, runTimeLinkSuccess = FALSE;
        LPFNDLLFUNC1 lpfnDllFunc1;    // Function pointer  
        if (args->IsEmpty())
        {
            dllHandle = LoadLibrary(L"TrueApplication.dll");
            if (NULL != dllHandle)
            {
                lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(dllHandle, "main");
                if (lpfnDllFunc1)
                {
                    int retVal = lpfnDllFunc1(0, "1");
                }

目前,LoadLibrary 调用有效,但 GetProcAddress 无效。

最佳答案

首先,将项目类型从可执行文件更改为DLL 不足以制作DLL。您还需要导出一些符号来创建您的 API。至少,您需要使用 __declspec(dllexport) 修饰要导出的函数。但是,我建议您导出 C API,这意味着 extern "C" 函数具有与 C 兼容的参数。因此,您导出的函数应该以 extern "C"__declspec(dllexport) 开头。

完成后,您可以像这样动态加载 DLL:

   const char* dllname = "myfile.dll";
   h = LoadLibrary(dllname);
   if( h == nullptr )
   {
       /*handle error*/
   }

   using myfunc_type = bool (*)(int x, double y); //example
   auto myfunc = reinterpret_cast<myfunc_type>(GetProcAddress(h, "myfunc"));       
   //......
   myfunc(x,y); //call the imported function

此解决方案比 Jerry Coffin 展示的使用 /delayload 进行静态加载需要更多的工作,但它有一个优势:如果需要 DLL 但未找到,您可以向用户提供您自己的错误消息依赖来自 Windows 的消息(这对于非技术人员来说通常是 Not Acceptable )。您还可以在 API 中包含 API 版本验证及其自己的自定义错误消息。

编辑:如果您这样更改,代码示例将起作用

extern "C" __declspec(dllexport) int main(int argc, char *argv[]){...}
typedef int (* LPFNDLLFUNC1)(int, char **);

关于c++ - 我怎样才能在运行时像可执行文件一样 "start"DLL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40939319/

相关文章:

loadlibrary - 来自市场的 java.lang.Runtime.loadLibrary 中的 java.lang.UnsatisfiedLinkError

c++ - 工厂设计模式如何处理不同长度的构造函数?

c++ - 数组分配后跟 memcpy 或 vector with reserve?

java - 如何管理所需的、冲突的 Java 依赖项

c# - c++\cli 项目依赖的 c++ dll 未复制到 c# 输出目录

c++ - 依赖于其他 DLL 的插件 DLL

c++ - 如何消除 LoadLibrary() 函数中变量类型不兼容的错误?

c++ - 如何通过opencv计算提取轮廓的曲率?

c++ - 这个 RLE 解码函数只解码第一个字符,我做错了什么?

c# - 在 C# 中与 C/C++ 例程交互会导致 rip