我应该如何共享进程和动态加载的多个DLL之间的函数列表?

时间:2017-03-07 04:23:53

标签: c++ dll plugins

我们在Windows CE 6.0中使用C ++编码的嵌入式应用程序(带有自定义硬件的自定义SDK,Visual Studio 2008,winapi应用程序)可以动态加载DLL并像插件一样使用它们。这种工作方式有助于我们公司根据客户的需求单独销售功能。

一些程序员希望两个插件能够在不调用可执行文件的功能的情况下相互通信。因此,它会让他们添加一个新功能,而不必强迫我总是编译主应用程序的新版本。

我认为,每个DLL都为进程提供了一个他们想要共享的函数列表。然后该过程将此列表提供给所有dll。我遇到的问题是每个函数都有不同的声明。我认为一组void指针适合这种情况,每个dll都会共享一个包含typedef函数的头文件。但我知道使用void指针是一种不好的做法,这意味着我的设计缺乏思考。

但是当我想要考虑它时,我找不到更好的方法。通过使用不同的函数而不使用函数的void指针来实现这一点的最佳方法是什么。

这是我思考的一个简单例子

U

1 个答案:

答案 0 :(得分:0)

如果你有一个固定的函数声明列表,你可以使用联合。

内部主程序

typedef struct item_fct{
    char* funcname;
    int funcID;
    int moduleID;
    void* funcnull;
} item_fct;

内部DLL

// ----------- plugins (dll)----------------
// function that the dll wants to share
typedef int (*funcintrf1) (int, int);
typedef int (*funcintrf2) (int, int, int);
typedef char (*funcintrf3) (int, int, double);
typedef double (*funcintrf4) (int, int, void*);

const int FUNC1_ID = 0x000101; 
const int FUNC2_ID = 0x000201; 
const int FUNC3_ID = 0x000301; 
const int FUNC4_ID = 0x000401; 

//synonyms
typedef struct funcdecl1 {
    int p1;
    int p2;
}

typedef struct funcdecl2 {
    int p1;
    int p2;
    int p3;
}

typedef struct funcdecl3 {
    int p1;
    int p2;
    double p3;
}

typedef struct funcdecl4 {
    int p1;
    int p2;
    void* p3;
}

typedef struct item_fct{
    char* funcname;
    int funcID;
    int moduleID;
    union {
        funcintrf1 func1;
        funcintrf2 func2;
        funcintrf3 func3;
        funcintrf4 func4;
        void* funcnull;
    };
} item_fct;

int calling_another_plugin_function(void* result, int amoduleID, int afuncID, void* aparams)
{
     item_fct* fct;
     for(size_t i = 0; i < list.size(); i++)
     {              
         if(list[i].funcID == afuncID && list[i].moduleID == amoduleID)
         {
             fct = list[i];
         }
     }
     if (amoduleID == 1) {
         switch (afuncID) {
            case FUNC1_ID : {
               funcdecl1 * p = (funcdecl1*)aparams;
               *((int*)result) = (*fct).func1((*p).p1, (*p).p2);
               break;
            }
            case FUNC2_ID : {
               funcdecl2 * p = (funcdecl2*)aparams;
               *((int*)result) = (*fct).func2((*p).p1, (*p).p2, (*p).p3);
               break;
            }
            case FUNC3_ID : {
               funcdecl3 * p = (funcdecl3*)aparams;
               *((char*)result) = (*fct).func3((*p).p1, (*p).p2, (*p).p3);
               break;
            }
         }
     }
}