首页 > 解决方案 > 我可以在 MSVC 项目中包含 GCC 生成的 DLL 吗?

问题描述

我有一个代码库,我正在为 Windows 应用程序从 x86 升级到 x64。

部分代码利用了 MSVC 内联汇编块。我不想通过和解释程序集,但我希望保留应用程序这一部分的功能。

我可以使用 GCC 使用内联程序集编译函数以制作 DLL 并将其链接到库的其余部分吗?

编辑 1:(7/7/21) 项目使用的编译器的灵活性是开放的,我目前正在研究使用 Clang 与 MSVC 一起使用。(也是英特尔 C++ 编译器作为另一种可能性)如第一句所述是我想保留在 Windows 上的 Windows 应用程序,使用另一个编译器的目的是由于我 1.) 不想重写大量程序集和 2.) 因为我知道 MSVC 不支持 x64 内联程序集。到目前为止,clang 似乎正在处理一些关于它如何在程序集块内声明注释和一些命令的问题。该功能是围绕对数据块进行数学运算而构建的,在开发时应该尽可能快,但现在它按预期工作,我不想升级只是维护功能。所以,

编辑 2:(7/7/21)我在第一次编辑中忘记提及,我不一定希望将 32 位 DLL 加载到另一个进程中,因为我担心将数据复制到共享内存之外。我为另一个项目做了类似的解决方案,但数据集大约 8 MB,我担心函数的慢复制时间会导致数学上的时间限制导致应用程序运行时出现问题。(慢,滞后和缓冲是我试图避免的影响。)我不想让它更快,但它绝对不能变得更慢。

标签: c++visual-studioassemblygccdll

解决方案


In theory, if you manage to create a plain C interface for that DLL (all exported symbols from DLL are standard C functions) and don't use memory management functions across "border" (no mixed memory management) then you should be able to dynamically load that DLL from another another (MSVC) process and call its functions, at least.

Not sure about statically linking against it... probably not, because the compiler and linker must go hand in hand (MSVC compiler+MSVC linker or GCC compiler+GCC linker) . The output of GCC linker is probably not compatible with MSVC at least regarding name mangling.

Here is how I would structure it (without small details):

Header.h (separate header to be included in both DLL and EXE)

//... remember to use your preferred calling convention but be consistent about it

struc Interface{
    void (*func0)();
    void (*func1)(int);
    //...
};

typedef Interface* (*GetInterface)();

DLL (gcc)

#include "Header.h"

//functions implementing specific functionality (not exported)
void f0)(){/*...*/}
void f1)(int){/*...*/}
//...

Interface* getInterface(){//this must be exported from DLL (compiler specific)
    static Interface interface;

    //initialize functions pointers from interface with corresponding functions
    interface.func0 = &f0;
    interface.func1 = &f1;
    //...

    return &interface;
}

EXE (MSVC)

#include "Header.h"
int main(){
    auto dll = LoadLibrary("DLL.dll");
    auto getDllInterface = (GetInstance)GetProcAddress(dll, "getInterface");
    auto* dllInterface = getDllInterface();

    dllInterface->func0();
    dllInterface->func1(123);
    //...
    return 0;
}


推荐阅读