D与C库集成导致输出乱码
D integrating with C library causes gibberish to be output
我有一个 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 的值却很好。
为什么会这样?
因为 .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");
一旦你获得了正确的调用约定,正确的结果应该会从调用中产生。
我有一个 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 的值却很好。
为什么会这样?
因为 .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");
一旦你获得了正确的调用约定,正确的结果应该会从调用中产生。