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

时间:2016-08-11 06:33:22

标签: 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);

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

现在,我试图在我的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

我使用:

编译testD.d

dmd testD.d

然后运行./testD

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

为什么会这样?

1 个答案:

答案 0 :(得分: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");

一旦你的呼叫约定正确,呼叫就会产生正确的结果。