【问题标题】:Loading dll in windows C for cross-platform design在 windows C 中加载 dll 以进行跨平台设计
【发布时间】:2019-05-01 00:24:54
【问题描述】:

我写了一个为 linux 平台设计的 c 代码。 现在,我想让它跨平台,以便在 Windows 中使用。 在我的代码中,我打开了一个 so 文件并利用其中的函数。 下面是我的代码的样子。但是我才发现,在windows中,加载和使用动态库的方式是完全不同的。

void *mydynlib
mydynlib= dlopen("/libpath/dynlib.so",RTLD_LAZY);
void (*dynfunc1)() = dlsym(mydynlib,"dynfunc1");
void (*dynfunc2)(char*, char*, double) = dlsym(mydynlib,"dynfunc2");
int (*dynfunc3)() = dlsym(mydynlib,"dynfunc3");

根据我的发现,我需要使用 LoadLibrary&GetProcAddress 而不是 dlopen&dlsym。但是,我不知道如何使用这些转换上面的行。我试图搜索几个小时的一些例子,但找不到确切的解决方案。如果有人有这种经验,请给我一个提示。 如果这是太明显的问题,请原谅。我对 C 很陌生。我通常用 python 编写程序。

【问题讨论】:

  • LoadLibrary 和 GetProcAddress 记录在 MSDN,这里有数十个(如果不是数百个)使用示例。您是否努力阅读文档、搜索现有帖子并尝试自己做一些事情?查看您发布的代码,自己转换它们应该是一项非常简单的任务,但除非您努力尝试,否则您无法做到这一点。您不会找到确切的示例,因为没有其他人有您要转换的确切代码。找到现有示例并对其进行调整以适应您的需求是您的工作。

标签: c windows dll shared-libraries dlopen


【解决方案1】:

您可以使用根据您所在操作系统而变化的宏:

#ifdef __linux__
#define LIBTYPE void*
#define OPENLIB(libname) dlopen((libname), RTLD_LAZY)
#define LIBFUNC(lib, fn) dlsym((lib), (fn))
#elif defined(WINVER)
#define LIBTYPE HINSTANCE
#define OPENLIB(libname) LoadLibraryW(L ## libname)
#define LIBFUNC(lib, fn) GetProcAddress((lib), (fn))
#endif

【讨论】:

    【解决方案2】:

    在我年轻的时候,我曾经创造过这样的东西:

    /* dlfcn.h */
    
    #ifndef DLFCN_H
    #define DLFCN_H
    
    #define RTLD_GLOBAL 0x100 /* do not hide entries in this module */
    #define RTLD_LOCAL  0x000 /* hide entries in this module */
    
    #define RTLD_LAZY   0x000 /* accept unresolved externs */
    #define RTLD_NOW    0x001 /* abort if module has unresolved externs */
    
    /*
       How to call in Windows:
    
       void *h = dlopen ("path\\library.dll", flags)
       void (*fun)() = dlsym (h, "entry")
    */
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
          void *dlopen  (const char *filename, int flag);
          int   dlclose (void *handle);
    
          void *dlsym   (void *handle, const char *name);
    
    const char *dlerror (void);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    

    和 dlfcn.c:

    /* dlfcn.c */ 
    
    #include <inttypes.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    
    static struct {
        long lasterror;
        const char *err_rutin;
    } var = {
        0,
        NULL
    };
    
    void *dlopen (const char *filename, int flags)
    {
        HINSTANCE hInst;
    
        hInst= LoadLibrary (filename);
        if (hInst==NULL) {
            var.lasterror = GetLastError ();
            var.err_rutin = "dlopen";
        }
        return hInst;
    }
    
    int dlclose (void *handle)
    {
        BOOL ok;
        int rc= 0;
    
        ok= FreeLibrary ((HINSTANCE)handle);
        if (! ok) {
            var.lasterror = GetLastError ();
            var.err_rutin = "dlclose";
            rc= -1;
        }
        return rc;
    }
    
    void *dlsym (void *handle, const char *name)
    {
        FARPROC fp;
    
        fp= GetProcAddress ((HINSTANCE)handle, name);
        if (!fp) {
            var.lasterror = GetLastError ();
            var.err_rutin = "dlsym";
        }
        return (void *)(intptr_t)fp;
    }
    
    const char *dlerror (void)
    {
    static char errstr [88];
    
        if (var.lasterror) {
            sprintf (errstr, "%s error #%ld", var.err_rutin, var.lasterror);
            return errstr;
        } else {
            return NULL;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-18
      • 1970-01-01
      • 2011-07-14
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      相关资源
      最近更新 更多