D与C库集成会导致输出乱码

Vla*_*lam 1 c d

我有一个C库,如下所示:

Abc.h文件

typedef struct
{
    uint8_t dbtype;
    uint32_t dbcount;
} Abc;

void test_string(Abc* abcobj, char* strA, char* strB);
Abc* create_abc(void);
Run Code Online (Sandbox Code Playgroud)

Abc.c

void test_string(Abc* abcobj, char* strA, char* strB)
{
    printf("Str A is %s and str B is %s\n", strA, strB);
    return;
}

Abc* create_abc()
{
    Abc* abcobj;
    abcobj = (Abc*) calloc(1, sizeof(Abc));
    return abcobj;
}
Run Code Online (Sandbox Code Playgroud)

现在,我试图在我的D代码中调用这些函数.

testD.d

module testD;

import std.stdio;
import core.stdc.string;
import core.sys.posix.dlfcn;

extern (C)
{
    struct Abc {
        ubyte dbtype;
        int dbcount;
    }
}

int main() {
    auto lib = dlopen("Abc.so".ptr, RTLD_LAZY | RTLD_LOCAL);

    if (lib is null) {
        return -1;
    }

    void function(Abc* abcobj, char* strA, char* strB) test_string = cast(void function(Abc* abcobj, char* strA, char* strB))dlsym(lib, "test_string");
    Abc* function() create_abc = cast(Abc* function())dlsym(lib, "create_abc");

    char* strA = cast(char*)("this is string one");
    char* strB = cast(char*)("this is string two");

    Abc* abcobj = create_abc();
    test_string(abcobj, strA, strB);

    if (dlclose(lib) == 0) {
        return 0;
    }
    else {
        return -1;
    }
} // main() function
Run Code Online (Sandbox Code Playgroud)

我使用以下命令编译testD.d:

dmd testD.d

然后运行./testD

当test_string输出句子时,strA的值总是出现乱码,而strB出来就好了.

为什么会这样?

Pet*_*esh 5

因为它.so是用C你编写的,你已经用C链接编译了库,但是当你导入符号时,你就丢弃了这个事实,这意味着D尝试使用D调用约定来调用代码,这与C召集会议.

导入函数时,需要指定此函数,因此dlsym行必须如下所示:

extern (C) void function(Abc* abcobj, char* strA, char* strB) test_string =
    cast(void function(Abc* abcobj, char* strA, char* strB))dlsym(lib, "test_string");
extern (C) Abc* function() create_abc =
    cast(Abc* function())dlsym(lib, "create_abc");
Run Code Online (Sandbox Code Playgroud)

一旦你获得正确的调用约定,就应该从调用中得出正确的结果.