Reputation: 95
Given the following c code snippet
#include<stdio.h>
#include "mcp2221_dll_um.h"
int main(void) {
wchar_t LibVersion[10];
int response = 0;
int error = 0;
response = Mcp2221_GetLibraryVersion(LibVersion);
if(response == 0) {
printf("Library (DLL) version: %ls \n",LibVersion);
} else {
error = Mcp2221_GetLastError();
printf("Version can't be found, version: %d, error %d\n", response, error);
}
}
with the function signature as defined in mcp2221_dll_um.h file
MCP2221_DLL_UM_API int CALLING_CONVENTION Mcp2221_GetLibraryVersion(wchar_t *version);
I compile the source using gcc: gcc -o test test.c -L. -lmcp2221_dll_um_x64
and run the executable: ./text.exe
then I get the following output: Library (DLL) version: 2.2b
GREAT it works as expected!
Now I would like to use python and ctypes to produce the same results.
So I wrote the following python code snippet
from ctypes import *
library = WinDLL("./mcp2221_dll_um_x64.dll")
library.Mcp2221_GetLibraryVersion.restype = c_int
library.Mcp2221_GetLibraryVersion.argtypes = [POINTER(c_wchar_p)]
LibVersion = c_wchar_p()
results = library.Mcp2221_GetLibraryVersion(LibVersion)
print("results: ", results)
print("LibVersion: ", LibVersion)
and run the code: python test.py
and get the following output
results: 0
LibVersion: c_wchar_p(27584762469223794)
The results 0 tells me the request was successful, but I am not sure how I can convert the LibVersion into a readable string which equals 2.2b like I get from running the c sample.
Please help me out here, I am using pointers the wrong way? or some other mistake?
Upvotes: 0
Views: 147
Reputation: 177471
c_wchar_p
is a pointer and equivalent to wchar_t*
in C. Just use .argtypes = [c_wchar_p]
.
Another issue is the API being called is using the wchar_t*
buffer as an out parameter, so you need to allocate a buffer to pass. This should work:
from ctypes import *
library = WinDLL("./mcp2221_dll_um_x64.dll")
library.Mcp2221_GetLibraryVersion.restype = c_int
library.Mcp2221_GetLibraryVersion.argtypes = c_wchar_p,
LibVersion = create_unicode_buffer(10)
results = library.Mcp2221_GetLibraryVersion(LibVersion)
print("results: ", results)
print("LibVersion: ", LibVersion.value)
Note that LibVersion.value
displays the null-terminated Unicode string in the buffer. If you needed to access the raw data you can use indexing or just copy the whole array out to a string with slicing:
>>> s=ctypes.create_unicode_buffer(10)
>>> s
<ctypes.c_wchar_Array_10 object at 0x000001E63085C7C8>
>>> s.value
''
>>> s[:]
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Upvotes: 1