简体   繁体   English

在Swig .i文件中,如何为基于第三方mfc的dll解析ms Windows vc ++ typedef类型?

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

I want to wrap a MFC C++ based SDK to a python module with swig. 我想用swig将基于MFC C ++的SDK包装到python模块。 But here I think the problem involves C++ and swig only. 但是在这里我认为问题只涉及C ++和swig。

Problem 问题

After compiling the .i file, when I started to build xxx_wrap.cxx, it raised an error. 编译.i文件后,当我开始构建xxx_wrap.cxx时,它引发了错误。

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

In cxx file, the error code is this VOID arg1 ; 在cxx文件中,错误代码是VOID arg1 ; .

In original .h file the error code is a constructor function of a class XXXxxx( VOID ); 在原始的.h文件中,错误代码是XXXxxx( VOID );类的构造函数XXXxxx( VOID );

First Try 第一次尝试

I thought this was because swig took VOID as a complex structure. 我认为这是因为swig将VOID视为一个复杂的结构。 I changed the VOID in .h file to void . 我将.h文件中的VOID更改为void But after a 'successful' compiling, the python can not import the module. 但是在“成功”编译之后,python无法导入模块。 Because the function declaration is not the same as the one in the SDK DLL. 因为函数声明与SDK DLL中的函数声明不同。

And the same problem happened in the LPCSTR . LPCSTR发生了同样的问题。

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

PS I have added the %include <windows.i> into the .i files. PS我已将%include <windows.i>到.i文件中。 But still the swig takes the VOID as a complex structure. 但是,仍然以VOID为复杂结构。

Question

How to write a right .i file for this kind of typedef? 如何为这种typedef编写正确的.i文件? Is there any other wrapped code example? 还有其他包装代码示例吗? I have searched stackoverflow and github, but got nothing. 我搜索了stackoverflow和github,但一无所获。

Possible Solution 可能的解决方案

Maybe I should write typedef in .i outside %{ ... }% section for swig other than just in .h file. 也许我应该在%{ ... }%部分之外的.i中为swig编写typedef,而不仅仅是在.h文件中。 But I don't know how. 但是我不知道如何。 I am currently reading the swig doc for a third time. 我目前正在第三次阅读Swig文档。

Restriction 限制

  • The DLL files are provided as a device SDK, and I don't have the source files. DLL文件是作为设备SDK提供的,我没有源文件。
  • From the .h files, we know that the DLL is based on multiple classes. 从.h文件中,我们知道DLL是基于多个类的。

     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. 我以前尝试过ctypes。 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. 我认为这是因为这是C ++的mumber函数。 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. 这就是为什么ctypes不适用于c ++类dll。

SDK SDK

The SDK provides 15 .h files, 17 .dll files and 4 .lib fils. 该SDK提供了15个.h文件,17个.dll文件和4个.lib fils。 It supports both unicode and multi-byte code. 它支持unicode和多字节代码。 It use a lot of LPCSTR and other string related typedefs. 它使用很多LPCSTR和其他与字符串相关的typedef。

Not sure what the issue is with VOID , need to see more code (such as, what is VOID defined as). 不确定VOID是什么问题,需要查看更多代码(例如VOID定义为什么)。

About LPCSTR , it is true that you can't convert. 关于LPCSTR ,确实不能转换。 One way to do it would be to put what is explained on C++ LPCTSTR to char* in a wrapper function in your .i. 一种实现方法是将C ++ LPCTSTR上解释的内容放在char *中的.i包装函数中。 The fact that it is a char** indicates the C++ function will probably return a pointer to an internal string. 它是char**的事实表明C ++函数可能会返回一个指向内部字符串的指针。 Python doesn't know how to handle that so you should return a string instance. Python不知道该如何处理,因此您应该返回一个字符串实例。 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). SWIG的%inline%extend指令使您可以完全使一个API适应另一个API(在这种情况下,将以char **作为arg的函数更改为返回字符串的函数)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM