Why do I need __declspec(dllexport) to make some functions accessible from ctypes?

后端 未结 1 1582
青春惊慌失措
青春惊慌失措 2021-01-01 07:55

So I am learning to make use of Python ctypes module.
Here is simple C file which I compiled with gcc -shared (version 4.8) on Windows to get sample .dll:



        
相关标签:
1条回答
  • 2021-01-01 08:12

    gcc seems to export functions by default, you can use any PE viewer like PE Explorer (View > Export) to view the exported functions:

    enter image description here

    But, If you try to compile this code with VC++, it won't export this function for you, you'll see that there is not exported function:

    enter image description here

    You need to ask it to export this function:

    __declspec(dllexport) int addition(int a, int b){
        return a+b;
    }
    

    As for calling conventions, the rule is simple:

    If your function uses __stdcall, as most Win32API, you need to import the DLL with WinDLL('mylib.dll') or windll.mylib, example:

    > type mylib.c
    __declspec(dllexport) int __stdcall addition(int a, int b) {
        return a+b;
    }
    
    ***********************************************************************
    
    > cl mylib.c /link /dll /out:mylib.dll
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
    
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    mylib.c
    Microsoft (R) Incremental Linker Version 8.00.50727.762
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /out:mylib.exe
    /dll
    /out:mylib.dll
    mylib.obj
       Creating library mylib.lib and object mylib.exp
    
    ***********************************************************************
    
    > python
    >>> from ctypes import *
    >>>
    >>> WinDLL('mylib.dll').addition(1, 2)
    3
    >>> windll.mylib.addition(1, 2)
    3
    >>>
    

    If your function uses __cdecl, witch is the default calling convention, you need to import the DLL with CDLL('mylib.dll') or cdll.mylib', example:

    > type mylib.c
    // `__cdecl` is not needed, since it's the default calling convention
    __declspec(dllexport) int addition(int a, int b){
        return a+b;
    }
    
    ***********************************************************************
    
    > cl mylib.c /link /dll /out:mylib.dll
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
    
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    mylib.c
    Microsoft (R) Incremental Linker Version 8.00.50727.762
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /out:mylib.exe
    /dll
    /out:mylib.dll
    mylib.obj
       Creating library mylib.lib and object mylib.exp
    
    ***********************************************************************
    
    > python
    >>> from ctypes import *
    >>>
    >>> CDLL('mylib.dll').addition(1, 2)
    3
    >>> cdll.mylib.addition(1, 2)
    3
    >>>
    
    0 讨论(0)
提交回复
热议问题