Software and hardware environment
ubuntu 18.04 64bit
windows 10 64bit
Python 3.8
GCC 4.9
visual studio
foreword
In doing python
development, it is often encountered that it is necessary C
to obtain the corresponding value by calling a dynamic link library of the. This article explains in detail the different implementations on Windows
the and Linux
2 platforms.
Dynamic library for linux
Write a simple C
code,test.c
#include <stdio.h>
#include <stdlib.h>
char * printStr(const char *p,const char *q)
{
printf("%s",p);
printf("%s",q);
return "djstava";
}
Compile into a dynamic link library by the following command
gcc -fPIC -shared -o libtest.so test.c
call in python3
To call C
functions in the library, you need to use ctypes
this module
from ctypes import *
handle = cdll.LoadLibrary('libtest.so')
func = handle.printStr
func.argtypes = (c_char_p,c_char_p)
func.restype = c_char_p
tmp = handle.printStr("hello".encode("utf-8"),"world".encode("utf-8"))
print(tmp.decode("utf-8"))
program execution result
helloworlddjstava
program explanation
func.argtypes = (c_char_p,c_char_p)
func.restype = c_char_p
These two sentences are to set the parameter data type and the return value type respectively. If you do not set it and call it directly, the parameter can be received normally, but the return value will always be a value, and the incoming string parameter must be , otherwise it will only be displayed in int
the encode("utf-8")
library c
. print as first character
handle = cdll.LoadLibrary('libtest.so')
ret = handle.printStr("hello".encode("utf-8"),"world".encode("utf-8"))
For settings of other data types argtypes
, please refer to the links in the references
Windows version of the dynamic library
Visual Studio
Compile dll
, add before the method that needs to be thrown __declspec(dllexport)
, such as the following C
code
__declspec(dllexport) unsigned int crc32( const unsigned char *s, unsigned int len)
{
unsigned int i;
unsigned int crc32val=0xffffffff;
printf("len==%d\n",len);
for (i = 0; i < len; i ++)
crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ ((crc32val >> 8)&0x00FFFFFF);
return ~crc32val;
}
Then open X64 Native Tools Command Prompt
the tool command line prompt, which cannot be used here powershell
orcmd
Go to C
the source code directory and execute the following two commands respectively. The first command is to generate the target file .obj
, and the second command is to link the target file to generate a dynamic library, which dll
is 64-bit
cl /c crc.c
link /dll crc.obj
At this point, dll
the file is generated, it is the dynamic link library we need, dll
the call so
is the same as the method of , so I won’t go into details here
Remark
If python
the following error is reported when executing the call
File "client.py", line 35, in <module>
data_crc = CRC.calcStrCRC(recv_buffer[20:], recv_buffer[8] - 14)
File "D:\longjing\clientdemo\crc.py", line 33, in calcStrCRC
handle = cdll.LoadLibrary('crc.dll')
File "D:\tools\anaconda3\lib\ctypes\__init__.py", line 426, in LoadLibrary
return self._dlltype(name)
File "D:\tools\anaconda3\lib\ctypes\__init__.py", line 348, in __init__
self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 不是有效的 Win32 应用程序。
There is a high probability that dll
the number of digits does not match. Here is a dll
way to check whether it is 32-bit or 64-bit, that is, use Visual Studio
the built-in tooldumpbin
dumpbin /headers libipanelcrc_64bit.dll
References
https://docs.python.org/3/library/ctypes.html