我试图在python中使用ctypes从dll调用C ++函数。我当前的问题是函数似乎返回一个大的int,无论是正数还是负数,而不是我期望它的char指针。如果我将该int转换为c_char_p并在其上调用.value,它每次都会杀死我的内核。我已经浏览了这个网站和文档,无法弄清楚这一点。我在这个网站上看到的很多东西甚至为我抛出错误,比如将字符串传递给ctypes opjects和函数时,它们应该是字节对象或类似的东西。下面是我的c ++代码,它变成了一个dll和我用来调用dll函数的python代码。如果有人能帮助我,那就太棒了。 SaySomething是有问题的功能。感谢。
#pragma once
#ifdef TESTLIBRARY_EXPORTS
#define TESTLIBRARY_API __declspec(dllexport)
#else
#define TESTLIBRARY_API __declspec(dllexport)
#endif
#include <windows.h>
#include <cstring>
#ifdef __cplusplus
extern "C"
{
#endif
TESTLIBRARY_API char* SaySomething(const char* phrase);
#ifdef __cplusplus
};
#endif
#include "stdafx.h"
#include "TestLibrary.h"
#include <iostream>
TESTLIBRARY_API char* SaySomething(const char* phrase)
{
char* p = new char [100];
p = "string something";
return p;
}
import ctypes
dbl = ctypes.c_double
pChar = ctypes.c_char_p
pVoid = ctypes.c_void_p
libName = (r"D:\Documents\Coding Stuff\Visual Studio 2017\Projects\TestLibrary"
r"Solution\x64\Debug\TestLibrary.dll")
x = ctypes.windll.LoadLibrary(libName)
x.SaySomething.argtypes = [pChar]
x.SaySomething.restypes = pChar
phrase = b"Hi"
phrase = pChar(phrase)
res = x.SaySomething(phrase)
答案 0 :(得分:3)
虽然您可以创建一个能够执行您要执行的操作的API,但您目前会发生内存泄漏。更好的解决方案是让Python为结果分配和管理内存。
我还修复了注释中提到的dllimport
,并在.cpp文件中定义了TESTLIBRARY_EXPORTS
,以便函数从DLL导出。 restype
也已修复。
<强> TesterLibrary.h 强>
#pragma once
#ifdef TESTLIBRARY_EXPORTS
#define TESTLIBRARY_API __declspec(dllexport)
#else
#define TESTLIBRARY_API __declspec(dllimport)
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
TESTLIBRARY_API char* SaySomething(const char* phrase, char* result, size_t resultMaxLength);
#ifdef __cplusplus
}
#endif
<强> TesterLibrary.cpp 强>
#define TESTLIBRARY_EXPORTS
#include "TestLibrary.h"
#include <stdio.h>
TESTLIBRARY_API char* SaySomething(const char* phrase, char* result, size_t resultMaxLength)
{
_snprintf_s(result,resultMaxLength,_TRUNCATE,"Decorated <%s>",phrase);
return result;
}
<强> tester2.py 强>
import ctypes
libName = (r"TestLibrary.dll")
x = ctypes.CDLL(libName)
x.SaySomething.argtypes = [ctypes.c_char_p,ctypes.c_char_p,ctypes.c_size_t]
x.SaySomething.restype = ctypes.c_char_p
phrase = b"Hi"
result = ctypes.create_string_buffer(100)
res = x.SaySomething(phrase,result,ctypes.sizeof(result))
print(res)
print(result.value)
<强>输出强>
b'Decorated <Hi>'
b'Decorated <Hi>'
当没有更多的引用时,Python将自动释放result
缓冲区。