簡體   English   中英

ctypes如何將字符串從python傳遞到c ++函數,以及如何將字符串從c ++函數返回到python

[英]ctypes how to pass string from python to c++ function, and how to return string from c++ function to python

我想從python調用一個c ++函數,這個c ++函數將char *作為參數,並返回字符串。 以下是我的代碼。

wrapper.cpp

#include <Python.h>
#include <string>
#include <iostream>

using namespace std;

extern "C"
string return_string(char* name){
    cout<<strlen(name)<<endl;
    cout<<name<<endl;
    string s = "hello ";
    s += name;
    return s;
}

將wrapper.cpp編譯為example.so

g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.7/

wrapper.py

import os
from ctypes import *

lib = cdll.LoadLibrary('./example.so')
lib.return_string.restype = c_char_p
lib.return_string.argtypes = [c_char_p]
name = create_string_buffer("Tom")
s = lib.return_string(name);
print s
print name

這是我的輸出

18
��H�L�l���A���
1
<ctypes.c_char_Array_4 object at 0x7f5f480be710>

如何使其工作?

這與ctypes無關; 您的C ++代碼本身無效。 您無法定義返回stringextern "C"函數。

在使用相同庫的C ++程序的快速測試中,它還會打印垃圾。

我還編寫了一個C程序,它定義了一個名為string東西,其布局與std::string相同,所以我可以編譯它,看看會發生什么; 它還打印垃圾,然后在~string

因此,Python程序也打印垃圾也就不足為奇了。

一切都很小,一切正常:

extern "C"
const char *return_string(char* name){
    cout<<strlen(name)<<endl;
    cout<<name<<endl;
    static string s = "hello ";
    s += name;
    return s.c_str();
}

我得到這個輸出:

3
Tom
hello Tom
<ctypes.c_char_Array_4 object at 0x11011c7a0>

(或者,從C ++版本開始,同樣的事情,但在最后一行使用“Tom”。)

當然,由於顯而易見的原因,這不是一個非常好的解決方案,但它表明返回string是個問題。

當我嘗試編譯你的C ++代碼時,g ++ - 4.5和clang-apple-4.0都提醒我這個問題(盡管g ++ - apple-4.2沒有,除非我添加了一個額外的-W標志)。 當編譯器給你一個警告時,這通常是“為什么我的代碼做錯了,即使它編譯”的答案。

您的代碼還有一些問題:

  • 您不能在.cpp文件中使用Python中的任何內容。 一般來說,使用ctypes的全部意義在於你的C或C ++代碼不必了解Python; 這是你的Python代碼知道它。 所以,不要包含或鏈接。
  • 如果你不打算修改它,那么采用非const char*通常是一個壞主意。 我的C ++司機曾與調用它const_cast<char*>(name.c_str())而不是僅僅name.c_str() 此外,這可以防止編譯器注意到您正在做的其他事情。

這是我上面提到的C ++驅動程序:

#include <iostream>
#include <string>
using namespace std;

extern "C" string return_string(char* name);

int main(int argc, char *argv[]) {
  string name("Tom");
  string s(return_string(const_cast<char *>(name.c_str())));
  cout << s << "\n";
  cout << name << "\n";
  return 0;
}

此外,如果我使用不同的優化設置或稍微重新組織代碼,在我的C ++驅動程序中,有時您的代碼實際上有效,有時它會打印垃圾,有時會出現段錯誤。 我的第一個猜測是,它取決於~string調用內聯的位置 - 但實際上,細節並不重要; 代碼不應該工作,它不會,所以誰在乎為什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM