Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
相当于python ctypes的C dll_Python_C_Dll_Ctypes - Fatal编程技术网

相当于python ctypes的C dll

相当于python ctypes的C dll,python,c,dll,ctypes,Python,C,Dll,Ctypes,我很有能力用python编写代码,但我想开始用C语言编写一些函数。使用ctypes,我可以很容易地打开DLL并使用函数。寻找这个等价物的简单C示例似乎是不可能的。我总是发现2页的C++例子充满了锅炉板代码,并不能真正地告诉我们正在发生什么。更糟糕的是,.Net和visual studio示例导入了各种依赖项。下面是运行良好的python代码,包括DLL函数的API文档 下面是我在代码::块中使用此dll的失败尝试 #include <windows.h> #include <s

我很有能力用python编写代码,但我想开始用C语言编写一些函数。使用ctypes,我可以很容易地打开DLL并使用函数。寻找这个等价物的简单C示例似乎是不可能的。我总是发现2页的C++例子充满了锅炉板代码,并不能真正地告诉我们正在发生什么。更糟糕的是,.Net和visual studio示例导入了各种依赖项。下面是运行良好的python代码,包括DLL函数的API文档

下面是我在代码::块中使用此dll的失败尝试

#include <windows.h>
#include <stdio.h>
#include "mcp2210_dll_um.h"

int main()
{   HINSTANCE hinstDLL;
    hinstDLL = LoadLibrary("mcp2210_dll_um_x86.dll");
    if (hinstDLL != 0){
        printf("DLL loaded ok");
        char *version;
        int VersionFunction;
        VersionFunction = GetProcAddress(hinstDLL, "Mcp2210_GetLibraryVersion");
        VersionFunction(*version);
        printf(version);
    }
    else{
        return -1;
    }
    FreeLibrary(hinstDLL);
    return 0;
}
#包括
#包括
#包括“mcp2210_dll_um.h”
int main()
{HINSTANCE hinstDLL;
hinstDLL=LoadLibrary(“mcp2210_dll_um_x86.dll”);
如果(hinstDLL!=0){
printf(“DLL加载正常”);
字符*版本;
int-VersionFunction;
VersionFunction=GetProcAddress(hinstDLL,“Mcp2210_GetLibraryVersion”);
VersionFunction(*版本);
printf(版本);
}
否则{
返回-1;
}
免费图书馆(hinstDLL);
返回0;
}
如果我省略了尝试运行函数的行,它似乎会构建和加载dll。在C中使用此DLL的最简单方法是什么?我得到的错误是:

…\dll_test_use\main.c | 13 |错误:调用的对象“VersionFunction”为 不是函数或函数指针|

编辑:***已解决**** @dgnuff是正确的

这就是我所需要做的:

#include <stdio.h>
#include "mcp2210_dll_um.h"
int main(){
    int ret_code;
    wchar_t version[64];
    ret_code = Mcp2210_GetLibraryVersion(version);
    printf("%d\n", ret_code);
    return 0;
}
#包括
#包括“mcp2210_dll_um.h”
int main(){
int ret_代码;
wchar__t版本[64];
ret_代码=Mcp2210_GetLibraryVersion(版本);
printf(“%d\n”,返回代码);
返回0;
}
之后,由于我使用的是code::blocks,我需要转到链接器设置并添加.lib文件

设置/编译器/链接设置/链接库:和添加 mcp2210_dll_um_x86.lib


这里有几个问题。首先
GetProcAddress()
返回命名函数入口点的地址。将其存储在
int
中不是一件有用的事情,因为您不能有意义地调用
int

在我脑海中,我无法告诉你
Mcp2210_GetLibraryVersion()
的签名,但是一个基于python的有根据的猜测说它类似于
int-Mcp2210_GetLibraryVersion(wchar\u t*version)。因此,您需要将
Mcp2210\u GetLibraryVersion
变量声明为指向相应函数签名的指针。web上有关于此详细信息的任意数量:

综上所述,虽然
LoadLibrary()
是从C代码访问DLL的一种方法,但出于许多原因,如果静态链接DLL,通常会更好。我注意到您的源代码中有这一行:

#include "mcp2210_dll_um.h"
它很可能是正在加载的DLL的“导入头”。如果是这种情况,那么您实际上不需要执行
LoadLibrary()
GetProcAddress()
sheanigans,您可以直接调用所讨论的例程,链接器/可执行加载程序将为您带来所有的魔力

这取决于它们是否是一个合适的
mcp2210_dll_um.lib
库文件,您可以将其链接到您的项目中:这就是“导入库”,它有助于实现这一切

另一个问题是,正如所写的那样,使用
version
变量几乎肯定不会像您希望的那样工作。这是一个完全不同的问题,正如在许多问题中提到的,数组和指针之间的差异和相似性在早期的C经验中可能会引起相当多的混淆

这里的底线假设
Mcp2210\u GetLibraryVersion()
确实采用宽字符指针,并用一个保存版本的字符串填充指向的位置

在这种情况下,您希望将版本声明为数组,而不是指针:

wchar_t version[64];
应该与python声明完全匹配:

version = (c_wchar * 64)()
在原始
char*版本中创建数组仅创建了一个指针
wchar\u t
是python的
C\u wchar
的C等价物

现在,要将该数组传递到
Mcp2210\u GetLibraryVersion()
中,只需将其命名为:

Mcp2210_GetLibraryVersion(version);
C(和C++)可能会对数组和指针的工作方式、它们各自是什么以及它们如何相互作用产生一些混淆

真正简短的答案是数组是固定的,无论它们在哪里声明,并且由指定数量的对象组成,所有对象在内存中彼此相邻

另一方面,指针是某物的地址。因此,仅仅声明一个指向(例如,
wchar\u t
的指针实际上并不会分配任何
wchar\u t
,它只会给您一些可以保存您选择的任何
wchar\u t
地址的内容

--编辑以澄清静态DLL的用法--

从您在评论中所说的内容来看,应该很简单,只要将头文件包含在C源文件中(您已经在这样做了),然后直接在C源文件中调用函数即可:

wchar_t version[64];
int retval = Mcp2210_GetLibraryVersion(version);
您需要小心地将
version
处理为
printf()
,因为version是一个宽字符串,默认情况下,
printf()
处理普通的
char
字符串。查看
\u wprintf()
\u tprintf()
以使其正常工作

至于库中的链接,如何实现这一点取决于您是直接从命令行或makefile调用链接器,还是作为Visual Studio项目进行构建

在前一种情况下,您将有类似

link.exe /option /option filename.obj other_filename.obj etc. etc. etc.
只需将库
mcp2210_dll_um_x86.lib
添加到命令行,它就可以工作了。请注意,如果库在其他目录中处于关闭状态,则可以使用
wchar_t version[64];
int retval = Mcp2210_GetLibraryVersion(version);
link.exe /option /option filename.obj other_filename.obj etc. etc. etc.