我有一个C库,如下所示:
typedef struct
{
uint8_t dbtype;
uint32_t dbcount;
} Abc;
void test_string(Abc* abcobj, char* strA, char* strB);
Abc* create_abc(void);
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代码中调用这些函数。
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.ddmd testD.d
然后运行./testD
当test_string输出句子时,strA的值总是出现乱码而strB出来就好了。
为什么会这样?
答案 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");
一旦你的呼叫约定正确,呼叫就会产生正确的结果。