python - 我想编写 ac 共享库以由 python 调用
问题描述
这是 c 'hello world' 代码
#include <stdio.h>
void hello(void) {
printf("Hello, World!\n");
}
我使用 clion IDE 和 gcc 编译器来编译代码。生成一个“.dll”共享库
这是python代码
import ctypes
dy = ctypes.cdll.LoadLibrary(r'C:\Users\ssc\CLionProjects\cpython\cmake-build-debug\libcpython.dll')
dy.hello()
这可以工作,它的输出
Hello, World!
但现在我在 c 中添加了一个多线程函数
#include <stdio.h>
#include <pthread.h>
void hello(void) {
printf("Hello, World!\n");
}
void *f1()
{
for(int ct=0;ct<100;ct++)
{
printf("thread 1 %d\n",ct);
}
pthread_exit(0);
}
void *f2()
{
for(int ct=0;ct<100;ct++)
{
printf("thread 2 %d\n",ct);
}
pthread_exit(0);
}
void print_thread(){
pthread_t p1;
pthread_t p2;
pthread_create(&p1, NULL,f1,NULL);
pthread_create(&p2, NULL,f2,NULL);
pthread_join(p1,NULL);
pthread_join(p2,NULL);
}
它可以编译为 dll 共享库,但是当我使用 python 调用时,它无法工作。这是错误信息
C:\Users\ssc\AppData\Local\Programs\Python\Python39\python.exe C:/Users/ssc/CLionProjects/cpython/test.py
Traceback (most recent call last):
File "C:\Users\ssc\CLionProjects\cpython\test.py", line 2, in <module>
dy = ctypes.cdll.LoadLibrary(r'C:\Users\ssc\CLionProjects\cpython\cmake-buil
d-debug\libcpython.dll')
File "C:\Users\ssc\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.
py", line 452, in LoadLibrary
return self._dlltype(name)
File "C:\Users\ssc\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.
py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'C:\Users\ssc\CLionProjects\cpython\cma
ke-build-debug\libcpython.dll' (or one of its dependencies). Try using the full
path with constructor syntax.
我将此代码添加到 ac 可执行程序中。它可以工作
C:\Users\ssc\CLionProjects\untitled2\cmake-build-debug\untitled2.exe
thread 1 0
thread 2 0
thread 2 1
thread 2 2
thread 2 3
...
...
我的代码有什么问题?
解决方案
问题似乎是找到 pthread 的 dll 文件。当您编译一个依赖于 pthreads 的共享库时,这只会将您创建的 dll 文件中的依赖项添加到该 dll 文件中。调用 LoadLibrary 时,需要找到此二阶依赖项。
我在 Linux 上,对 Windows 不太熟悉,但您可以查看LoadLibrary 的文档,了解它在哪里搜索依赖项。
在 Linux 上,我可以获取您的 c 代码并对其进行编译,gcc -shared threads.c -o libthre.so -fPIC -pthread
然后在 python 中运行它:
import ctypes
lib_th = ctypes.cdll.LoadLibrary("./libthre.so")
lib_th.hello()
lib_th.print_thread()
我还可以ldd
用来验证它是否找到了 pthread 库:
$ ldd libthre.so
linux-vdso.so.1 (0x00007ffe758ec000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd1cd62b000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd1cdc1e000)
如果 pthread 库不在搜索目录中,我可以rpath
在编译/链接共享库时指定它,或者在运行 python 程序时使用 LD_LIBRARY_PATH 环境变量指定它。然而,这些在 Windows 中的工作方式有所不同,所以很遗憾,我不能确切地告诉你如何在那里做。也许您可以尝试将 pthread dll 复制到与您自己的 dll 文件相同的文件夹中,作为测试。
推荐阅读
- firebase - 从颤振模型自动生成firebase表
- string - 有没有办法在飞镖运行时分配/编辑 String[i][j] 值?
- python - 我正在尝试将 numpy.ndarray 转换为张量输入到我的模型
- python - NameError: pip install moviepy 后未定义名称'moviepy'
- sql - PostgreSQL:我想为用户提供模式访问,用户不应该看到其他模式名称,如何实现?
- facebook-graph-api - Facebook API 评论返回 200 错误
- c# - 如何验证动态(Expando)对象?
- lua - 增量时间和低估(我不了解增量时间)
- git - 从历史记录中删除过去的(双重)合并提交
- flutter - 在android 11中长时间颤动后收到Firebase消息