简体   繁体   中英

Loading dll in windows C for cross-platform design

I wrote a c-code designed for linux platform. Now, I want to make it cross-platform so to use in Windows as-well. In my code, I dlopen an so file and utilize the functions inside it. Below is how my code looks like. But I just found out that in windows, the way to load and use dynamic library is quite different.

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");

From what I found, I need to use LoadLibrary&GetProcAddress instead of dlopen&dlsym. However, I do not know how to convert above line for windows using those. I've tried to search some examples for hours but couldn't find exact solution. If someone had this kind of experience, please give me a tip. Excuse me if this is too obvious problem. I'm quite new to C. I usually write my program in python.

You could use macros that change depending on the OS you're on:

#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

Once in my youth I created something like this:

/* 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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM