【发布时间】:2018-02-12 08:24:50
【问题描述】:
我为现有库 (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:符号查找错误:/usr/lib/libmylib.so:未定义符号:wiringPiSetup
这里出了什么问题?
我的第一个想法是,我的程序不知道 WiringPi 库。所以我为这个 dll 添加了一个导出并调用wiringPiSetup() 进行测试。不管有没有这个语句,结果都是一样的。
我还在我的自定义库中添加了一个没有wiringPi 依赖项的测试函数。这在 C# 中调用得很好。
我是不是在链接时搞砸了?
编辑:
命令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)
【问题讨论】:
-
你不是已经问过了吗?
-
请注意this question 中LD_DEBUG 的用法,以获取更多故障排除信息。
-
ldd /usr/lib/libmylib.so说什么?是否包含libwiringPi.so? -
我将输出添加到我的问题中。
-
名字装饰? codeguru.com/csharp/csharp/cs_data/article.php/c4217/… 会不会有这样的工作:[DllImport("TestDll.dll", EntryPoint="myproc", ExactSpelling=false,CallingConvention=CallingConvention.Cdecl)]
标签: c# raspberry-pi shared-libraries .net-core pinvoke