In a swig .i file, how to resolve ms windows vc++ typedef type for 3rd party mfc based dll?

StackOverflow https://stackoverflow.com/questions/22085918

  •  18-10-2022
  •  | 
  •  

문제

I want to wrap a MFC C++ based SDK to a python module with swig. But here I think the problem involves C++ and swig only.

Problem

After compiling the .i file, when I started to build xxx_wrap.cxx, it raised an error.

error C2182: 'arg1' : illegal use of type 'void'

In cxx file, the error code is this VOID arg1 ;.

In original .h file the error code is a constructor function of a class XXXxxx( VOID );

First Try

I thought this was because swig took VOID as a complex structure. I changed the VOID in .h file to void. But after a 'successful' compiling, the python can not import the module. Because the function declaration is not the same as the one in the SDK DLL.

And the same problem happened in the LPCSTR.

cannot convert from 'char **' to 'LPCSTR *'

PS I have added the %include <windows.i> into the .i files. But still the swig takes the VOID as a complex structure.

Question

How to write a right .i file for this kind of typedef? Is there any other wrapped code example? I have searched stackoverflow and github, but got nothing.

Possible Solution

Maybe I should write typedef in .i outside %{ ... }% section for swig other than just in .h file. But I don't know how. I am currently reading the swig doc for a third time.

Restriction

  • The DLL files are provided as a device SDK, and I don't have the source files.
  • From the .h files, we know that the DLL is based on multiple classes.

    class A;
    
    class B;
    
    class C;
    
    class __declspec(dllexport) D
    
    {
        ...
    
    private:    
    
        friend class A;
    
        friend class B;
    
        friend class C;
    
    }
    
  • I have tried the ctypes before. The import was OK, but when I called a function, it raised an exception.

    exception: access violation writing 0x1D1A9446

    I think it is because this is a C++ mumber function. The code want to access a class member variant, which is out of the range of the function. That's why ctypes doesn't work for c++ class dll.

SDK

The SDK provides 15 .h files, 17 .dll files and 4 .lib fils. It supports both unicode and multi-byte code. It use a lot of LPCSTR and other string related typedefs.

도움이 되었습니까?

해결책

Not sure what the issue is with VOID, need to see more code (such as, what is VOID defined as).

About LPCSTR, it is true that you can't convert. One way to do it would be to put what is explained on C++ LPCTSTR to char* in a wrapper function in your .i. The fact that it is a char** indicates the C++ function will probably return a pointer to an internal string. Python doesn't know how to handle that so you should return a string instance. Example:

%inline %{
    std::string myFunc() // don't use char** since 
    {
         LPCTSTR pszA = ... create buffer for LPCSTR string
         callYourMFCFunc(& pszA);
         CStringA sB(pszA);
         return std::string((const char*)sB);
    }
%}

I haven't tested the above, it is my best guess based on that SO post so you might have to fix a bit but you get the idea. SWIG's %inline and %extend directives allow you to completely adapt one API to another (in this case, change a function that takes a char** as arg into a function that returns a string).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top