【发布时间】:2021-01-08 23:02:21
【问题描述】:
我正在开发一种编程语言,我希望它能够访问 dll(或共享库)。我知道 python 有一个 CDLL 函数可以做到这一点。在C语言中,我知道要调用dll函数,必须使用LoadLibrary加载库,并使用GetProcAddress获取过程,最后将其转换为函数。
typedef void (__stdcall *testf)();
HINSTANCE lib = LoadLibrary("test.dll");
testf proc = (testf) GetProcAddress(lib, "testf");
proc();
但是在python中,第三步没有做完。
from ctypes import *
lib = CDLL("test.dll")
lib.testf() #not casting the function anywhere
这是如何完成的,如何在 C 中实现相同的目标?
【问题讨论】:
-
Python 似乎在后台执行该步骤,我不明白您如何绕过需要找到加载到内存中的函数的地址。
-
它不知道,它使用了duck-typing。尝试传递错误的参数,看看会发生什么。您的问题的所有答案都可以通过阅读documentation获得。
-
python 是自己执行这个任务,还是有一些底层的 C 代码。我的印象是 C 在后台运行,如果是,C 代码不应该需要强制转换吗?
-
不清楚具体的实现,希望有人能给你一个彻底的答案。但是,强制转换实际上只是装饰性的,它给指针一个类型,所以
foo()在语法上是正确的。没有什么可以阻止您转换为错误的签名,因此ctypes的 C impl 可以转换为您调用函数的签名,并捕获错误调用函数可能产生的任何异常。请参阅链接中的“外来函数”部分。或者它可以利用int(*)()是一个接受任何参数的函数这一事实并做同样的事情。 -
后者更有可能,它也符合默认情况下库期望函数返回
int的声明。由于 C 没有模板,因此演员表必须硬连线。void*(*)()是我猜的最通用的。