ctypes.ArgumentError when calling DLL functions with Python

后端 未结 2 1914
粉色の甜心
粉色の甜心 2020-12-21 14:49

I\'m using ctypes to call functions in a DLL file according to a description file that describe the DLL functions\' parameters and returns. Here is one function in this DLL

相关标签:
2条回答
  • 2020-12-21 15:27

    ctypes official doc: [Python 3.5]: ctypes - A foreign function library for Python.

    Created a dummy .dll to mimic your behavior.

    dll.c:

    #include <stdio.h>
    #include <Windows.h>
    
    
    __declspec(dllexport) BOOL InitNetwork(char LocalIP[], char ServerIP[], int LocalDeviceID) {
        printf("From C:\n\tLocalIP: [%s]\n\tServerIP: [%s]\n\tLocalDeviceID: %d\n", LocalIP, ServerIP, LocalDeviceID);
        return TRUE;
    }
    

    Check [SO]: How to compile a 64-bit dll written in C? (@CristiFati's answer) for details how to build it (took the exact same steps, command in this case was: cl /nologo /LD /DWIN64 /DWIN32 /Tp dll.c /link /OUT:NetServerInterface.dll).

    The (main) problem is that in Python3, char* no longer maps to a string, but to a bytes object.

    code.py:

    import sys
    import ctypes
    from ctypes import wintypes
    
    
    FILE_NAME = "NetServerInterface.dll"
    FUNC_NAME = "?InitNetwork@@YAHQEAD0H@Z"  # Name different than yours: if func was declared as `extern "C"`, the "normal" name would be required
    
    
    def main():
        net_server_interface_dll = ctypes.CDLL(FILE_NAME)
        init_network = getattr(net_server_interface_dll, FUNC_NAME)
    
        init_network.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int]
        init_network.restype = wintypes.BOOL
    
        init_network(b"192.168.1.103", b"192.168.1.103", 1111)
    
    
    if __name__ == "__main__":
        print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
        main()
    

    Output:

    (py35x64_test) e:\Work\Dev\StackOverflow\q050325050>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
    Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
    
    From C:
            LocalIP: [192.168.1.103]
            ServerIP: [192.168.1.103]
            LocalDeviceID: 1111
    
    0 讨论(0)
  • 2020-12-21 15:33

    I think the problem is in your C++ interface. I think if you change it to Function:BOOL InitNetwork(char * LocalIP,char * ServerIP,int LocalDeviceID);

    your first call (without the keywords) should work but I think you might need to remove the quotes around the last argument (it is an int after all).

    0 讨论(0)
提交回复
热议问题