gpt4 book ai didi

c# - .net core - PInvoke C 共享库函数依赖于另一个共享库

转载 作者:行者123 更新时间:2023-11-30 16:42:47 25 4
gpt4 key购买 nike

我为现有库 ( wiringPi ) 编写了一些包装代码来读取温度传感器,但在使用此库时出现错误。

我的包装库看起来像:

mylib.h

#ifndef mylib_h__
#define mylib_h__
extern void read_sensor();
#endif

mylib.c

#include "mylib.h"
#include <wiringPi.h>

void read_sensor() {
//here is the first call on the wiringPi lib
if (wiringPiSetup() == -1)
exit(1);

...
}

然后我使用 gcc 编译我的库:

gcc -Wall -Werror -fPIC -c mylib.c
gcc -shared -o libmylib.so mylib.o -lwiringPi
cp libmylib.so /usr/lib/

提示如果正常使用此库的 C 程序,一切正常。

现在我的 C# 程序使用 PInvoke 从这个库中调用 read_sensor():

程序.cs

class Program 
{
[DllImport("wiringPi")]
static extern int wiringPiSetup();

[DllImport("mylib")]
static extern void read_sensor();

static void Main(string[] args)
{
wiringPiSetup();
read_sensor();
}
}

此程序使用以下参数编译:

dontet publish -r linux-arm

并复制到我的 Raspberry-Pi。

现在我执行这个 C# 程序并抛出以下错误:

./my-program-name: symbol lookup error: /usr/lib/libmylib.so: undefined symbol: wiringPiSetup

这里出了什么问题?

我的第一个想法是,我的程序不知道 wiringPi 库。所以我为这个 dll 添加了一个导出并调用了 wiringPiSetup() 进行测试。使用或不使用此语句的结果相同。

我还在自定义库中添加了一个不依赖 wiringPi 的测试函数。这在 C# 中称为 fine。

我是不是在链接时搞砸了什么?

编辑:

命令 ldd/usr/lib/libmylib.so 给出了这个输出:

linux-vdso.so.1 (0x7efad000)
/usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76f73000)
libwiringPi.so => /usr/local/lib/libwiringPi.so (0x76f40000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76dff000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76d84000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76d5c000)
librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76d45000)
libcrypt.so.1 => /lib/arm-linux-gnueabihf/libcrypt.so.1 (0x76d05000)
/lib/ld-linux-armhf.so.3 (0x54abc000)

最佳答案

归结为名称装饰。 C++ 编译器不只是将函数的名称放入目标文件中 - 它会根据函数的定义(最显着的是它的参数)向名称添加信息。

来自 https://msdn.microsoft.com/en-us/library/56h2zst2.aspx

Functions, data, and objects in C and C++ programs are represented internally by their decorated names. A decorated name is an encoded string created by the compiler during compilation of an object, data, or function definition. It records calling conventions, types, function parameters and other information together with the name. This name decoration, also known as name mangling, helps the linker find the correct functions and objects when linking an executable.

但是编译的 C 代码不会这样做 - 名称修饰(或名称修饰)随 C++ 一起出现。

因此,您必须告诉 C#“此函数的名称未修饰。”

为此使用如下属性:

[DllImport("TestDll.dll", EntryPoint="myproc", ExactSpelling=false,CallingConvention=CallingConvention.Cdec‌​l)]

是“CallingConvention”位表示“该函数是一个 C 函数。”

“Cdecl”的意思是“C 声明”,如果我没记错的话。

更多信息请访问:http://www.codeguru.com/csharp/csharp/cs_data/article.php/c4217/Calling-Unmanaged-Code-Part-1--simple-DLLImport.htm

关于c# - .net core - PInvoke C 共享库函数依赖于另一个共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46031271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com