如何使用 python 中的 Char** 参数和 int* 参数调用 C 方法?



这是加载包含io.cio.h文件的erf_utils_io_D.dllmodule.py script我成功地加载了库并传递了 ctype 参数,例如

c_int, c_float, 指针(c_int), 指针(c_Float)

module.py

//python code module.py
import sys
from ctypes import *
#load the required library and make sure the folder where    erf_utils_io_D.dll is present
dll = CDLL('D:\erf_utils_python\erf_utils_io.dll')
getContourResults = dll.getContourResults
class Utility(object):
def __init__(self):
print('i am inside init')
self.stagename = "post"
self.stateids = (c_int * 1) (2934)
self.stateidcount = 1
self.entityidcount = 1
self.entityid = (c_int * 1) (1)
self.entitytype = "FPM"
self.variablecount = 1
self.ores = [1.0]
self.filename ='allinone_RESULT.erfh5'
#This is how char** is treted in python for variablegroup
self.variablegroup = ["FPM_Mach_Number"]
self.string_length = len(self.variablegroup)
self.select_type = (c_wchar_p * self.string_length)
self.select = self.select_type()
for key, item in enumerate(self.variablegroup):
self.select[key] = item

#This is how char** is treated infor variable
self.variable = ["FPM_Mach_Number"]
self.var_len = len(self.variable)
self.var_type = (c_wchar_p * self.var_len)
self.variable_list = self.var_type()
for key, item in enumerate(self.variable):
self.variable_list[key] = item

def run(self):
getContourResults.argtypes = (POINTER(c_char_p), POINTER(c_char_p), c_int, POINTER(c_int),
c_int, POINTER(c_int), POINTER(c_char), c_int, self.select_type ,
self.var_type, POINTER(c_float))
getContourResults.restype = (c_int)

err = getContourResults(self.filename, self.stagename, self.stateidcount,
self.stateids, self.entityidcount,self.entityid, self.entitytype, self.variablecount, self.select, self.variable_list, self.ores)

reader = Utility()
reader.run()

代码.cpp看起来像这样

extern "C"
{
#endif
__declspec(dllexport) int getContourResults(char* iFilename, char* iStagename, int iStateidCnt, int* Stateids,
int iEntityIdCount, int* iEntityids, char* iEntityType,
int iVariablecnt, char** iVariablegroup, char** ivariable,
float* oResults);
}

请让我知道如何将参数从python 脚本传递到io.c 中getContourResults()的方法

没有指示该函数的实现,因此我做了一些假设。 通过此示例,您应该能够适应您的实际用例。 主要修复是.argtypes更正并使用c_char_p而不是c_wchar_p以及一个简单的帮助程序函数将列表转换为 ctypes 数组。

以下是有关类型的一些说明:

  • c_char_p==char*在 C 中。 传递一个字节字符串,例如b'string'.
  • c_wchar_p== C 中的wchar_t*。 传递一个 Unicode 字符串,例如'string'.
  • POINTER(c_char_p)==char**在 C 中。
  • POINTER(c_float)== C 中的float*。 创建存储(c_float())并传递byref。 访问返回的浮点数作为具有.value成员的 Python 整数。

测试.cpp

#include <stdio.h>
extern "C" __declspec(dllexport) int getContourResults(char* iFilename, char* iStagename, int iStateidCnt, int* Stateids,
int iEntityIdCount, int* iEntityids, char* iEntityType,
int iVariablecnt, char** iVariablegroup, char** ivariable,
float* oResults)
{
printf("iFilename = %sn"
"iStagename = %sn"
,iFilename,iStagename);
for(int i = 0; i < iStateidCnt; ++i)
printf("Stateids[%d] = %dn",i,Stateids[i]);
for(int i = 0; i < iEntityIdCount; ++i)
printf("iEntityids[%d] = %dn",i,iEntityids[i]);
printf("iEntityType = %sn",iEntityType);
for(int i = 0; i < iVariablecnt; ++i) {
printf("iVariablegroup[%d] = %sn",i,iVariablegroup[i]);
printf("ivariable[%d] = %sn",i,ivariable[i]);
}
*oResults = 1.2f;
return 5;
}

test.py

from ctypes import *
dll = CDLL('./test')
dll.getContourResults = dll.getContourResults
dll.getContourResults.argtypes = (c_char_p,c_char_p,c_int,POINTER(c_int),c_int,POINTER(c_int),c_char_p,
c_int,POINTER(c_char_p),POINTER(c_char_p),POINTER(c_float))
dll.getContourResults.restype = c_int
def make_array(ctype,arr):
return len(arr),(ctype * len(arr))(*arr)
def getContourResults(filename,stagename,sids,eids,entitytype,groups,variables):
stateidcount,stateids = make_array(c_int,sids)
entityidcount,entityid = make_array(c_int,eids)
groups = [b'group1',b'group2']
variables = [b'var1',b'var2']
if len(groups) != len(variables):
raise ValueError('assuming groups and variables same length')
_,variablegroup = make_array(c_char_p,groups)
variablecount,variable = make_array(c_char_p,variables)
ores = c_float()
err = dll.getContourResults(filename,stagename,stateidcount,stateids,entityidcount,entityid,
entitytype,variablecount,variablegroup,variable,byref(ores))
return err,ores.value
sids = [1,2,3]
eids = [4,5,6]
groups = [b'group1',b'group2']
variables = [b'var1',b'var2']
err,ores = getContourResults(b'filename',b'stagename',sids,eids,b'entitytype',groups,variables)
print(f'err = {err}')
print(f'ores = {ores:.2f}')

输出:

iFilename = filename
iStagename = stagename
Stateids[0] = 1
Stateids[1] = 2
Stateids[2] = 3
iEntityids[0] = 4
iEntityids[1] = 5
iEntityids[2] = 6
iEntityType = entitytype
iVariablegroup[0] = group1
ivariable[0] = var1
iVariablegroup[1] = group2
ivariable[1] = var2
err = 5
ores = 1.20

相关内容

最新更新