c与c++ 如何同时混编混岗

Matlab与C/C++联合编程之Matlab以MEX方式调用C/C++代码(三)
最近写了个Matlab程序,好慢呐……所以开始学习Matlab与C/C++混合编程。下面写了个测试代码,显示一个Double类型矩阵中的元素。
#include &mex.h&
void displaySubscript( const mxArray *pArray, mwSize index );
// 入口函数
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
& & // 源文件名后缀为.c时,所有变量声明必须一次性完成,且放在最前面, 否则mex编译错误
& & // 源文件名后缀为.cpp时,没有上面的问题,...- -||
& & double *pD
& & // 输入参数必须为一个,且为double类型
& & if ( nrhs != 1 || mxDOUBLE_CLASS != mxGetClassID(prhs[0]) ) {
& & & & mexErrMsgTxt( &输入参数不合法……& );
& & // 获取数据指针
& & pData = mxGetPr(prhs[0]);
& & // 遍历所有元素并打印到屏幕
& & for ( i = 0; i != mxGetNumberOfElements(prhs[0]); i++ ) {
& & & & displaySubscript( prhs[0], i );
& & & & mexPrintf( & = %g/n&, pData[i] );
void displaySubscript( const mxArray *pArray, mwSize index ) {
& & // 源文件名后缀为.c时,所有变量声明必须一次性完成,且放在最前面, 否则mex编译错误
& & // 源文件名后缀为.cpp时,没有上面的问题,...- -||,代码好龊...
& & mwSize i,
& & mwSize numOfD
& & mwSize *subS
& & mwSize subI
& & const mwSize *D
& & const char *classN
& & // 获取维度个数
& & numOfDim = mxGetNumberOfDimensions(pArray);
& & // 获取维度数组
& & Dims = mxGetDimensions(pArray);
& & // 获取类型名称
& & className = mxGetClassName(pArray);
& & // 分配下标数组内存
& & subScript = (mwSize *)mxCalloc( numOfDim, sizeof( mwSize ) );
& & // 根据当前的索引号生成下标
& & subIndex =
& & for ( i = numOfDim - 1; ; i-- ) {
& & & & total = 1;
& & & & for ( j = 0; j & j++ ) {
& & & & & & total *= Dims[j];
& & & & subScript[i] = subIndex /
& & & & subIndex = subIndex %
& & & & if ( 0 == i ) {
& & & & & &
& & // 打印出所有下标
& & mexPrintf( &(& );
& & for ( i = 0; i & numOfDim - 1; i++ ) {
& & & & mexPrintf( &%d,&, subScript[i] + 1 );
& & mexPrintf( &%d)&, subScript[numOfDim-1] + 1 );
& & // 释放下标数组内存
& & mxFree( subScript );
在Matlab使用mex命令编译源文件时,要注意这样一个现象:源文件名后缀为.c时,所有变量声明必须一次性完成,且放在最前面, 否则mex编译错误;而源文件名后缀为.cpp时,就没有上面的问题,...- -||。
混合编程API一览
MX Matrix Library
mwIndex (C and Fortran)
Type for index values
mwPointer (Fortran)
Pointer type for platform
mwSignedIndex (C and Fortran)
Signed integer type for size values
mwSize (C and Fortran)
Type for size values
mxAddField (C and Fortran)
Field to structure array
mxArray (C and Fortran)
Type for MATLAB array
mxArrayToString (C)
Convert array to string
mxAssert (C)
Check assertion value for debugging purposes
mxAssertS (C)
Check assertion value without printing assertion text
mxCalcSingleSubscript (C and Fortran)
Offset from first element to desired element
mxCalloc (C and Fortran)
Allocate dynamic memory for array using MATLAB memory manager
mxChar (C)
Type for string array
mxClassID (C)
Enumerated value identifying class of array
mxClassIDFromClassName (Fortran)
Identifier corresponding to class
mxComplexity (C)
Flag specifying whether array has imaginary components
mxCopyCharacterToPtr (Fortran)
CHARACTER values from Fortran array to pointer array
mxCopyComplex16ToPtr (Fortran)
COMPLEX*16 values from Fortran array to pointer array
mxCopyComplex8ToPtr (Fortran)
COMPLEX*8 values from Fortran array to pointer array
mxCopyInteger1ToPtr (Fortran)
INTEGER*1 values from Fortran array to pointer array
mxCopyInteger2ToPtr (Fortran)
INTEGER*2 values from Fortran array to pointer array
mxCopyInteger4ToPtr (Fortran)
INTEGER*4 values from Fortran array to pointer array
mxCopyPtrToCharacter (Fortran)
CHARACTER values from pointer array to Fortran array
mxCopyPtrToComplex16 (Fortran)
COMPLEX*16 values from pointer array to Fortran array
mxCopyPtrToComplex8 (Fortran)
COMPLEX*8 values from pointer array to Fortran array
mxCopyPtrToInteger1 (Fortran)
INTEGER*1 values from pointer array to Fortran array
mxCopyPtrToInteger2 (Fortran)
INTEGER*2 values from pointer array to Fortran array
mxCopyPtrToInteger4 (Fortran)
INTEGER*4 values from pointer array to Fortran array
mxCopyPtrToPtrArray (Fortran)
Pointer values from pointer array to Fortran array
mxCopyPtrToReal4 (Fortran)
REAL*4 values from pointer array to Fortran array
mxCopyPtrToReal8 (Fortran)
REAL*8 values from pointer array to Fortran array
mxCopyReal4ToPtr (Fortran)
REAL*4 values from Fortran array to pointer array
mxCopyReal8ToPtr (Fortran)
REAL*8 values from Fortran array to pointer array
mxCreateCellArray (C and Fortran)
Unpopulated N-D cell array
mxCreateCellMatrix (C and Fortran)
Unpopulated 2-D cell array
mxCreateCharArray (C and Fortran)
Unpopulated N-D string array
mxCreateCharMatrixFromStrings (C and Fortran)
Create populated 2-D string array
mxCreateDoubleMatrix (C and Fortran)
2-D, double-precision, floating-point array initialized to 0
mxCreateDoubleScalar (C and Fortran)
Scalar, double-precision array initialized to specified value
mxCreateLogicalArray (C)
N-D logical array initialized to false
mxCreateLogicalMatrix (C)
2-D, logical array initialized to false
mxCreateLogicalScalar (C)
Scalar, logical array
mxCreateNumericArray (C and Fortran)
Unpopulated N-D numeric array
mxCreateNumericMatrix (C and Fortran)
Numeric matrix initialized to 0
mxCreateSparse (C and Fortran)
2-D unpopulated sparse array
mxCreateSparseLogicalMatrix (C)
Unpopulated 2-D, sparse, logical array
mxCreateString (C and Fortran)
Create 1-by-N array initialized to specified string
mxCreateStructArray (C and Fortran)
Unpopulated N-D structure array
mxCreateStructMatrix (C and Fortran)
Unpopulated 2-D structure array
mxDestroyArray (C and Fortran)
Free dynamic memory allocated by MXCREATE* functions
mxDuplicateArray (C and Fortran)
Make deep copy of array
mxFree (C and Fortran)
Free dynamic memory allocated by MXCALLOC, MXMALLOC, or MXREALLOC functions
mxGetCell (C and Fortran)
Contents of array cell
mxGetChars (C)
Pointer to character array data
mxGetClassID (C and Fortran)
Class of array
mxGetClassName (C and Fortran)
Class of array as string
mxGetData (C and Fortran)
Pointer to real data
mxGetDimensions (C and Fortran)
Pointer to dimensions array
mxGetElementSize (C and Fortran)
Number of bytes required to store each data element
mxGetEps (C and Fortran)
Value of EPS
mxGetField (C and Fortran)
Field value, given field name and index, into structure array
mxGetFieldByNumber (C and Fortran)
Field value, given field number and index, into structure array
mxGetFieldNameByNumber (C and Fortran)
Field name, given field number, in structure array
mxGetFieldNumber (C and Fortran)
Field number, given field name, in structure array
mxGetImagData (C and Fortran)
Pointer to imaginary data of array
mxGetInf (C and Fortran)
Value of infinity
mxGetIr (C and Fortran)
Sparse matrix IR array
mxGetJc (C and Fortran)
Sparse matrix JC array
mxGetLogicals (C)
Pointer to logical array data
mxGetM (C and Fortran)
Number of rows in array
mxGetN (C and Fortran)
Number of columns in array
mxGetNaN (C and Fortran)
Value of NaN (Not-a-Number)
mxGetNumberOfDimensions (C and Fortran)
Number of dimensions in array
mxGetNumberOfElements (C and Fortran)
Number of elements in array
mxGetNumberOfFields (C and Fortran)
Number of fields in structure array
mxGetNzmax (C and Fortran)
Number of elements in IR, PR, and PI arrays
mxGetPi (C and Fortran)
Imaginary data elements in array of type DOUBLE
mxGetPr (C and Fortran)
Real data elements in array of type DOUBLE
mxGetProperty (C and Fortran)
Value of public property of MATLAB object
mxGetScalar (C and Fortran)
Real component of first data element in array
mxGetString (C and Fortran)
String array to C-style string
mxIsCell (C and Fortran)
Determine whether input is cell array
mxIsChar (C and Fortran)
Determine whether input is string array
mxIsClass (C and Fortran)
Determine whether array is member of specified class
mxIsComplex (C and Fortran)
Determine whether data is complex
mxIsDouble (C and Fortran)
Determine whether mxArray represents data as double-precision, floating-point numbers
mxIsEmpty (C and Fortran)
Determine whether array is empty
mxIsFinite (C and Fortran)
Determine whether input is finite
mxIsFromGlobalWS (C and Fortran)
Determine whether array was copied from MATLAB global workspace
mxIsInf (C and Fortran)
Determine whether input is infinite
mxIsInt16 (C and Fortran)
Determine whether array represents data as signed 16-bit integers
mxIsInt32 (C and Fortran)
Determine whether array represents data as signed 32-bit integers
mxIsInt64 (C and Fortran)
Determine whether array represents data as signed 64-bit integers
mxIsInt8 (C and Fortran)
Determine whether array represents data as signed 8-bit integers
mxIsLogical (C and Fortran)
Determine whether array is of type mxLogical
mxIsLogicalScalar (C)
Determine whether scalar array is of type mxLogical
mxIsLogicalScalarTrue (C)
Determine whether scalar array of type mxLogical is true
mxIsNaN (C and Fortran)
Determine whether input is NaN (Not-a-Number)
mxIsNumeric (C and Fortran)
Determine whether array is numeric
mxIsSingle (C and Fortran)
Determine whether array represents data as single-precision, floating-point numbers
mxIsSparse (C and Fortran)
Determine whether input is sparse array
mxIsStruct (C and Fortran)
Determine whether input is structure array
mxIsUint16 (C and Fortran)
Determine whether array represents data as unsigned 16-bit integers
mxIsUint32 (C and Fortran)
Determine whether array represents data as unsigned 32-bit integers
mxIsUint64 (C and Fortran)
Determine whether array represents data as unsigned 64-bit integers
mxIsUint8 (C and Fortran)
Determine whether array represents data as unsigned 8-bit integers
mxLogical (C)
Type for logical array
mxMalloc (C and Fortran)
Allocate dynamic memory using MATLAB memory manager
mxRealloc (C and Fortran)
Reallocate dynamic memory using MATLAB memory manager
mxRemoveField (C and Fortran)
Remove field from structure array
mxSetCell (C and Fortran)
Value of one cell of array
mxSetClassName (C)
Convert structure array to MATLAB object array
mxSetData (C and Fortran)
Set pointer to data
mxSetDimensions (C and Fortran)
Modify number of dimensions and size of each dimension
mxSetField (C and Fortran)
Set structure array field, given structure field name and array index
mxSetFieldByNumber (C and Fortran)
Set structure array field, given field number and index
mxSetImagData (C and Fortran)
Imaginary data pointer for array
mxSetIr (C and Fortran)
IR array of sparse array
mxSetJc (C and Fortran)
JC array of sparse array
mxSetM (C and Fortran)
Number of rows in array
mxSetN (C and Fortran)
Set number of columns in array
mxSetNzmax (C and Fortran)
Set storage space for nonzero elements
mxSetPi (C and Fortran)
Set new imaginary data for array
mxSetPr (C and Fortran)
Set new real data for array
mxSetProperty (C and Fortran)
Set value of public property of MATLAB object
MEX Library
mexAtExit (C and Fortran)
Register function to call when MEX-function cleared or MATLAB software terminates
mexCallMATLAB (C and Fortran)
Call MATLAB function, user-defined function, or MEX-file
mexCallMATLABWithTrap (C and Fortran)
Call MATLAB function, user-defined function, or MEX-file and capture error information
mexErrMsgIdAndTxt (C and Fortran)
Display error message with identifier and return to MATLAB prompt
mexErrMsgTxt (C and Fortran)
Display error message and return to MATLAB prompt
mexEvalString (C and Fortran)
Execute MATLAB command in caller workspace
mexEvalStringWithTrap (C and Fortran)
Execute MATLAB command in caller workspace and capture error information
mexFunction (C and Fortran)
Entry point to C/C++ or Fortran MEX-file
mexFunctionName (C and Fortran)
Name of current MEX-function
mexGet (C)
Value of specified Handle Graphics property
mexGetVariable (C and Fortran)
Copy of variable from specified workspace
mexGetVariablePtr (C and Fortran)
Read-only pointer to variable from another workspace
mexIsGlobal (C and Fortran)
Determine whether variable has global scope
mexIsLocked (C and Fortran)
Determine whether MEX-file is locked
mexLock (C and Fortran)
Prevent clearing MEX-file from memory
mexMakeArrayPersistent (C and Fortran)
Make array persist after MEX-file completes
mexMakeMemoryPersistent (C and Fortran)
Make memory allocated by MATLAB software persist after MEX-function completes
mexPrintf (C and Fortran)
ANSI C PRINTF-style output routine
mexPutVariable (C and Fortran)
Array from MEX-function into specified workspace
mexSet (C)
Set value of specified Handle Graphics property
mexSetTrapFlag (C and Fortran)
Control response of MEXCALLMATLAB to errors
mexUnlock (C and Fortran)
Allow clearing MEX-file from memory
mexWarnMsgIdAndTxt (C and Fortran)
Warning message with identifier
mexWarnMsgTxt (C and Fortran)
Warning message
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?基于Linux的Fortran与C/C++混合编程_论文_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&100W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
基于Linux的Fortran与C/C++混合编程
中国最大最早的专业内容网站|
总评分0.0|
&&Fortran、C/C++是用户数量最多,使用最为广泛的编程语言.存在大量优秀的软件包及源代码,通过混合编程可以合并不同语言的优势,充分利用目前存在的这些软件资源。分析在Linux系统中Fortran与C/C++混合编程基本原理和内部调用约定.并通过实例阐述了使用C/C++调用Fortran77编写的线性代数软件包LAPACK的方法。实践表明,这种方法有效且可靠。
试读已结束,如果需要继续阅读或下载,敬请购买
定制HR最喜欢的简历
你可能喜欢C++与C#互调dll的实现步骤
转载 &更新时间:日 10:19:58 & 投稿:shichen2014
这篇文章主要介绍了C++与C#互调dll的实现步骤,dll动态链接库的共享在一些大型项目中有一定的应用价值,需要的朋友可以参考下
本文实例展示了C++与C#互调dll的实现步骤,在进行大型项目共享dll动态链接库中可以用到。具体方法如下:
一、C#调用C++ dll步骤(只能导出方法):
1. c++建立空项目-&源文件文件夹中添加cpp文件和函数
2. c++属性设置中,配置类型设置为动态库dll,公共语言运行时支持改为/clr
3. c#引用c++的dll
4. c#声明c++的方法,并添加 DllImport特性
5. c#工程属性设置为:目标平台x86
6. 注意方法的类型匹配
7. 引发PInvokeStackImbalance异常:注意:C++的"_declspec"和C#的“CallingConvention=CallingConvention.Cdecl”
另外,可以通过VS的异常窗口,取消掉对 PInvokeStackImbalance异常的检测:
点击VS的“调试 - 异常”,打开异常窗口,展开选择“Managed Debugging Assistants\PInvokeStackImbalance”,去掉对应的“引发”可选框。&
二、 c++调用 c# dll的步骤(可直接使用C#类):
1. 创建c++控制台应用程序
2. 拷贝c# dll到c++工程根目录
3. 工程属性-&配置-&常规-&公共语言运行时支持-&clr
工程属性-&配置-&c/c++常规-&调试信息格式-&zi
工程属性-&配置-&c/c++常规-&公共语言运行时支持-&clr
#using "CSharpDllProject.dll"
using namespace CSharpDllP
三、 c#调用c++类步骤(c++/cli,可直接使用C++类)
c++/cli简介:C++/CLI标准是基于Microsoft提交的标准C++与通用语言基础结构(Common Language Infrastructure)结合的技术
1.使用c++/cli语法对标准c++类进行包装(可采用聚合模式,引用标准c++类,实现所有标准c++的方法)
2.c#引用c++ dll后,可直接new出一个 c++/cli创建的托管类对象
希望本文所述方法对大家有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具很好的c++和Python混合编程文章 - Earvin - 博客园
随笔 - 13, 文章 - 11, 评论 - 3, 引用 - 0
本人是用vc2003+python2.5学习的,其它的也应该差不了多少
0. 坏境设置把的include/libs目录分别加到vc的include/lib directories中去。另外,由于python没有提供debug lib,体地说,就是没有提供python25_d.lib了。你可以自己编译python的源代码来得到python25_d.lib的,偶还没试过,呵呵。而且网上找了一下也没下载到。所以,如果你想要在debug下运行程序的话,你要把pyconfig.h(在python25/include/目录下)的大概是在283行,把pragma comment(lib,"python25_d.lib")改成pragma comment(lib,"python25.lib"),让python都使用非debug lib.
1. 开始编程了#include &python.h&第一步就是包含python的头文件
2. 看一个很简单的例子1)python文件test.py,很简单的定义了一个函数
#Filename test.pydef Hello():&&& print "Hello, world!"
这个应该能看懂的吧?否则的话,回去再练练python吧,呵呵。《简明Python教程》Swaroop, C. H. 著。沈洁元& 译。
#include &python.h& //包含头文件,在c++中嵌入python,这是必须的int main(){&Py_Initialize();
&PyObject * pModule = NULL;&PyObject * pFunc&& = NULL;
&pModule = PyImport_ImportModule("test");&pFunc&& = PyObject_GetAttrString(pModule, "Hello");&PyEval_CallObject(pFunc, NULL);
&Py_Finalize();
&return 0;}
第一步还是包含头文件
第二步,使用python之前,要调用Py_Initialize();这个函数进行初始化。帮助文档中如是说:The basic initialization function is Py_Initialize(). This initializes the table of loaded modules, and creates the fundamental modules __builtin__, __main__, sys, and exceptions. It also initializes the module search path (sys.path).
反正,一开始你一定要调用。
第三步,声明一些Python的变量,PyObject类型的。其实声明也可放在前面,这个倒是无所谓的。
第四步,import module,也就是你的脚本名字,不需要加后缀名,否则会出错的。
第五步,从你import进来的module中得到你要的函数&pFunc&& = PyObject_GetAttrString(pModule, "Hello");上面的例子已经够清楚的了,最后一个是你要得到的函数的名字
第六步,调用PyEval_CallObject来执行你的函数,第二个参数为我们要调用的函数的函数,本例子不含参数,所以设置为NULL。
第七步,调用Py_Finalize,这个根Py_Initialize相对应的。一个在最前面,一个在最后面。
第一次写教程。这个例子非常简单,本人也还在学习当中阿,只能保证大家能够把这个例子运行起来。建议大家去看python的documentaion,里面有讲怎么embedding python的。先写到这里,其实目前也只学到这么多,呵呵。下次学了更多以后再写。Over。恩。
1. 一个有一个参数的例子
python文件#Filename test2.py
def Hello(s):&&& print "Hello, world!"&&& print s
cpp文件#include &python.h&int main(){&Py_Initialize();
&PyObject * pModule = NULL;&PyObject * pFunc&& = NULL;&PyObject * pArg&&& = NULL;
&pModule = PyImport_ImportModule("test2");&pFunc&& = PyObject_GetAttrString(pModule, "Hello");&pArg&&& = Py_BuildValue("(s)", "function with argument");
&PyEval_CallObject(pFunc, pArg);
&Py_Finalize();
&return 0;}
注意,参数要以tuple元组形式传入。因为这个函数只要一个参数,所以我们直接使用(s)构造一个元组了。
2. 一个有两个参数的例子
python文件中加入以下代码,一个加函数def Add(a, b):&&& print "a+b=", a+b
cpp文件,只改了两行,有注释的那两行#include &python.h&int main(){&Py_Initialize();
&PyObject * pModule = NULL;&PyObject * pFunc&& = NULL;&PyObject * pArg&&& = NULL;
&pModule = PyImport_ImportModule("test2");&pFunc&& = PyObject_GetAttrString(pModule, "Add");//终于告别hello world了,开始使用新的函数&pArg&&& = Py_BuildValue("(i,i)", 10, 15);//构造一个元组
&PyEval_CallObject(pFunc, pArg);
&Py_Finalize();
&return 0;}
其它的就类似了。。。基本上,我们知道了怎么在c++中使用python中的函数。接下来学习一下如何使用python中的
附:Py_BuildValue的使用例子,来自python documentation:
&&& Py_BuildValue("")&&&&&&&&&&&&&&&&&&&&&&& None&&& Py_BuildValue("i", 123)&&&&&&&&&&&&&&&&& 123&&& Py_BuildValue("iii", 123, 456, 789)&&&&& (123, 456, 789)&&& Py_BuildValue("s", "hello")&&&&&&&&&&&&& 'hello'&&& Py_BuildValue("ss", "hello", "world")&&& ('hello', 'world')&&& Py_BuildValue("s#", "hello", 4)&&&&&&&&& 'hell'&&& Py_BuildValue("()")&&&&&&&&&&&&&&&&&&&&& ()&&& Py_BuildValue("(i)", 123)&&&&&&&&&&&&&&& (123,)&&& Py_BuildValue("(ii)", 123, 456)&&&&&&&&& (123, 456)&&& Py_BuildValue("(i,i)", 123, 456)&&&&&&&& (123, 456)&&& Py_BuildValue("[i,i]", 123, 456)&&&&&&&& [123, 456]&&& Py_BuildValue("{s:i,s:i}",&&&&&&&&&&&&&&&&& "abc", 123, "def", 456)&&& {'abc': 123, 'def': 456}&&& Py_BuildValue("((ii)(ii)) (ii)",&&&&&&&&&&&&&&&&& 1, 2, 3, 4, 5, 6)&&&&&&&&& (((1, 2), (3, 4)), (5, 6))
这次主要讲讲怎么把python中的class嵌入到c++中去。顺便讲讲元组的操作和怎么编译python源代码。
1. 首先讲讲元组的操作由于参数是通过元组传进去的,所以我们不能老是通过Py_BuildValue这个函数来操作元组,那样太不方便了。Python提供了元组相关的操作,下面这个例子演示了如何操作。主要是下面几个函数://new一个元组,传入sizepArgs = PyTuple_New(argc - 3);&//set元组的直,第一个为元组,第二个为index(从0开始),第三个为valuePyTuple_SetItem(pArgs,0,Py_BuildValue("i",2000) );PyTuple_SetItem(pArgs,1,Py_BuildValue("i",8) );
来自python doc的一个例子
#include &Python.h&intmain(int argc, char *argv[]){&&& PyObject *pName, *pModule, *pDict, *pF&&& PyObject *pArgs, *pV&&&
&&& if (argc & 3) {&&&&&&& fprintf(stderr,"Usage: call pythonfile funcname [args]/n");&&&&&&& return 1;&&& }
&&& Py_Initialize();&&& pName = PyString_FromString(argv[1]);&&& /* Error checking of pName left out */
&&& pModule = PyImport_Import(pName);&&& Py_DECREF(pName);
&&& if (pModule != NULL) {&&&&&&& pFunc = PyObject_GetAttrString(pModule, argv[2]);&&&&&&& /* pFunc is a new reference */
&&&&&&& if (pFunc && PyCallable_Check(pFunc)) {&&&&&&&&&&& pArgs = PyTuple_New(argc - 3);&&&&&&&&&&& for (i = 0; i & argc - 3; ++i) {&&&&&&&&&&&&&&& pValue = PyInt_FromLong(atoi(argv[i + 3]));&&&&&&&&&&&&&&& if (!pValue) {&&&&&&&&&&&&&&&&&&& Py_DECREF(pArgs);&&&&&&&&&&&&&&&&&&& Py_DECREF(pModule);&&&&&&&&&&&&&&&&&&& fprintf(stderr, "Cannot convert argument/n");&&&&&&&&&&&&&&&&&&& return 1;&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&& /* pValue reference stolen here: */&&&&&&&&&&&&&&& PyTuple_SetItem(pArgs, i, pValue);&&&&&&&&&&& }&&&&&&&&&&& pValue = PyObject_CallObject(pFunc, pArgs);&&&&&&&&&&& Py_DECREF(pArgs);&&&&&&&&&&& if (pValue != NULL) {&&&&&&&&&&&&&&& printf("Result of call: %ld/n", PyInt_AsLong(pValue));&&&&&&&&&&&&&&& Py_DECREF(pValue);&&&&&&&&&&& }&&&&&&&&&&& else {&&&&&&&&&&&&&&& Py_DECREF(pFunc);&&&&&&&&&&&&&&& Py_DECREF(pModule);&&&&&&&&&&&&&&& PyErr_Print();&&&&&&&&&&&&&&& fprintf(stderr,"Call failed/n");&&&&&&&&&&&&&&& return 1;&&&&&&&&&&& }&&&&&&& }&&&&&&& else {&&&&&&&&&&& if (PyErr_Occurred())&&&&&&&&&&&&&&& PyErr_Print();&&&&&&&&&&& fprintf(stderr, "Cannot find function /"%s/"/n", argv[2]);&&&&&&& }&&&&&&& Py_XDECREF(pFunc);&&&&&&& Py_DECREF(pModule);&&& }&&& else {&&&&&&& PyErr_Print();&&&&&&& fprintf(stderr, "Failed to load /"%s/"/n", argv[1]);&&&&&&& return 1;&&& }&&& Py_Finalize();&&& return 0;}
2. class操作把下面加入到test2.py中去。定义了一个很简单的类,有一个name成员变量,一个printName成员函数class TestClass:&&& def __init__(self,name):&&&&&&& self.name = name
&&& def printName(self):&&&&&&& print self.name
cpp文件#include &python.h&int main(){&Py_Initialize();
&PyObject * pModule = NULL;&PyObject * pFunc&& = NULL;&PyObject * pArg&&& = NULL;&PyObject * pClass& = NULL;&PyObject * pObject = NULL;
&pModule = PyImport_ImportModule("test2");&pClass& = PyObject_GetAttrString(pModule, "TestClass");//得到那个类&pArg = PyTuple_New(1);&PyTuple_SetItem(pArg, 0, Py_BuildValue("s", "Jacky"));&pObject = PyEval_CallObject(pClass, pArg);//生成一个对象,或者叫作实例
&pFunc = PyObject_GetAttrString(pObject, "printName");//得到该实例的成员函数&PyEval_CallObject(pFunc, NULL);//执行该实例的成员函数
&Py_Finalize();
&return 0;}
没有什么资料,就先写到这里了。下面介绍一下怎么build python25的源代码
3. 编译python源代码为什么要编译呢?因为没有python25_d.lib!呵呵。顺便可以了解一下代码结构。解压缩后,有好多目录,其中pcbuild和pcbuild8是我们要的。pcbuild对应着vc7.1的,pcbuild8对应着vc8.0的因为在用vc7.1,也就是2003了。所以我就说说怎么用2003来编译吧。事实上是从一位牛人那里学来的
,那位大哥大概一年半前就在解剖python了,厉害
阿。看来我只能后来居上了,娃哈哈。我按照他说的试了一下,编译成功!
不过遇到一点小问题,用vc2003打开那个solution的时候,发现作者没有把source code control去掉,郁闷!害的我
们打开的时候一堆messagebox。不过不用管它就好了,一直确定。最后试了一下那个python25_d.lib,没问题。不过记
得把python25_d.dll copy到一个能被找到的目录,比如说c:/windows/system32/下面。python25.dll也在这个目录下
面。over。恩。
坏境python25 + vs真耗资源阿。。。)
有一段时间没写blog了。这几天都在研究怎么封装c++,让python可以用c++的库。在网上发现了boost.python这个好咚咚。不
过在使用过程中碰到一点问题。本文教大家如何把
char const* greet(){&& return "hello, world";}
封装成python。实际上这是python教程里面的咚咚。
首先下载Boost,。boost.python在boost里面了。在visual studio 2005 command prompt中navigation到
boost/boost_1_34_0/下。记得一定要用visual studio 2005 command prompt这个vs2005带的tools,不要用cmd.exe,否则会
碰到很多错误的。然后就是把bjam.exe拷贝到一个能被找到的目录下,或者直接也拷贝到boost/boost_1_34_0/下即可。然后,
设置python的根目录和python的版本,也可直接把它们加到坏境目录中,那样就不用每次都设置一下。set PYTHON_ROOT=c:/python25set PYTHON_VERSION=2.5
接着就可以直接运行了,bjam -sTOOLS=vc-8_0整个编译过程要很长时间。。。
成功之后,就会有好多个boost_python-vc80-****.dll,.lib的,把他们都拷贝到一个能被系统找到的目录,不妨直接把他们都
扔到c:/windows/system32下。
接着,我们开始编译hello。navigation到boost/boost_1_34_0/libs/python/example/tutorial下,bjam -sTOOLS=vc-8_0运行
,在bin的目录下即会生成hello.pyd。这下就基本成功了,如果没成功的话,check一下上面boost_python的那些dll能否被系
统找到。另外,这里有python25的一个bug。。。我花了很长时间才在python的mail lists中找到了。寒。。。
错误如下所示:D:/Learn/Python/boost/boost_1_34_0/libs/python/example/tutorial&bjamJamroot:17: in modules.loadrule python-extension unknown in module Jamfile&/D:/Learn/Python/boost/boost_1_34_0/libs/python/example/tutorial&.D:/Learn/Python/boost/boost_1_34_0/tools/build/v2/build/project.jam:312: in load-jamfileD:/Learn/Python/boost/boost_1_34_0/tools/build/v2/build/project.jam:68: in loadD:/Learn/Python/boost/boost_1_34_0/tools/build/v2/build/project.jam:170: in project.findD:/Learn/Python/boost/boost_1_34_0/tools/build/v2/build-system.jam:237: in loadD:/Learn/Python/boost/boost_1_34_0/libs/python/example/../../../tools/build/v2/kernel/modules.jam:261: in importD:/Learn/Python/boost/boost_1_34_0/libs/python/example/../../../tools/build/v2/kernel/bootstrap.jam:132: in boost-buildD:/Learn/Python/boost/boost_1_34_0/libs/python/example/boost-build.jam:7: in module scope
解决办法如下:在boost/boost_1_34_0/tools/build/v2/目录下找到user-config.jam文件,打开在import toolset :下面加一行代码:再重新编译一下boost,然后就没问题了。tutorial里面的hello能顺利编译通过。ps.这个问题困扰了我好长时间。。sigh。。
编译成功后会产生一个hello.pyd,在bin的目录下面。
有好多办法测试此hello.pyd是否可以用。方法一,把它拷贝到python25/dlls下,打开IDLE,&&& import hello&&& hello.greet()'hello, world'&&&&方法二,直接在当前目录下写一个python文件,然后直接调用hello.pyd即可。总之,hello.pyd就是一个python文件了。。嗯
。操作hello.pyd根其他python文件是一样的。这样就成功了。
如果碰到如下错误,是因为系统找不到boost_python的dll。强烈建议把他们都扔到system32下!。
&&& import hello
Traceback (most recent call last):& File "&pyshell#0&", line 1, in &module&&&& import helloImportError: DLL load failed: 找不到指定的模块。&&&
说明,hello.cpp在boost/boost_1_34_0/libs/python/example/tutorial目录下。里面的内容是:
//& Copyright Joel de Guzman . Distributed under the Boost//& Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt&//& or copy at&)//& Hello World Example from the tutorial//& [Joel de Guzman 10/9/2002]
char const* greet(){&& return "hello, world";}
#include &boost/python/module.hpp&#include &boost/python/def.hpp&using namespace boost::
BOOST_PYTHON_MODULE(hello){&&& def("greet", greet);}
其中BOOST_PYTHON_MODULE(hello){&&& def("greet", greet);}是对greet从c++向python的一个封装声明吧,装换就交给boost了。
先写到这里了。下次再写。。嗯
这次讲讲,如何扩展c++库。通过boost.python把c++库编译成python能够调用的dll。
通过上一次的教程后,大家都应该会使用boost.python了。把c++程序编译成pyd文件。由于c++有很多特性,所以,如果你的程
序用了很多的c++特性的话,那么你必须做很多工作了。像虚拟函数,函数重载,继承,默认值等等。具体如何转化,请参
boost.python的文档了。
这几天尝试着把c++程序库编译成python可调用的dll,不知道为什么一直不可用。。很是郁闷。老是显示如下的错误:
Traceback (most recent call last):& File "&pyshell#3&", line 1, in &module&&&& import pydllImportError: No module named pydll
意思是说找不到dll。我把dll都copy到python/dlls下了还是不行,而且我确定python的sys.path包含了python/dlls目录了。
很是不解。网上也很难找到资料,google了很长时间找不到有用的资料,好像中文方面的资料很少的。今天尝试了一下google
英文资料,终于有了新的发现:You are using Python2.5. In this version of Python you have to havefile extensionto be "pyd" - sge.pyd
--&Roman YakovenkoC++ Python language binding
有人碰到的问题跟我的是一样的。后面那个Roman回答了一下,是文件扩展名的问题!!!为什么不支持dll呢?不解。回去试
了一下把后缀名改了就成功了。。。why???
下面来看一下我的那个简单的例子:这个例子来自于网上,C++ 扩展和嵌入 Python作者:胡金山源码下载地址:
这是一个非常简单的dll工程。给python提供了一个函数static PyObject* Recognise(PyObject *self, PyObject *args)。
1、不使用boost.python库来直接构建dll接下来,我们来用C++为Python编写扩展模块(动态链接库),并在Python程序中调用C++开发的扩展功能函数。生成一个取名为
pyUtil的Win32 DLL工程,除了pyUtil.cpp文件以外,从工程中移除所有其它文件,并填入如下的代码:
// pyUtil.cpp#ifdef PYUTIL_EXPORTS#define PYUTIL_API __declspec(dllexport)#else#define PYUTIL_API __declspec(dllimport)#endif
#include&windows.h&#include&string&#include&Python.h&BOOL APIENTRY DllMain( HANDLE hModule,&&&&&&&&&&&&&&&&&&&&&&& DWORD& ul_reason_for_call,&&&&&&&&&&&&&&&&&&&&&&& LPVOID lpReserved&&&&&&& ){&&& switch (ul_reason_for_call)&&& {&&& case DLL_PROCESS_ATTACH:&&& case DLL_THREAD_ATTACH:&&& case DLL_THREAD_DETACH:&&& case DLL_PROCESS_DETACH:&&&&&&&&&& }&&& return TRUE;}std::string Recognise_Img(const std::string url){&&& //返回结果&&& return "从dll中返回的数据... : " +}static PyObject* Recognise(PyObject *self, PyObject *args){&&& const char *&&& std::&&& if (!PyArg_ParseTuple(args, "s", &url))&&&&&&& return NULL;&&& sts = Recognise_Img(url);&&& return Py_BuildValue("s", sts.c_str() );}static PyMethodDef AllMyMethods[] = {&&& {"Recognise",& Recognise, METH_VARARGS},//暴露给Python的函数&&& {NULL,&&&&& NULL}&&&&&&& /* Sentinel */};extern "C" PYUTIL_API void initpyUtil(){&&& PyObject *m, *d;&&& m = Py_InitModule("pyUtil", AllMyMethods); //初始化本模块,并暴露函数&&& d = PyModule_GetDict(m);}
在Python代码中调用这个动态链接库: (记得把dll的扩展名改为.pyd,另外dll的路径要能够被检索到)import pyUtilresult = pyUtil.Recognise("input url of specific data")print "the result is: "+ result
2、使用boost.python库来构建dll用C++为Python写扩展时,如果您愿意使用Boost.Python库的话,开发过程会变得更开心J,要编写一个与上述pyUtil同样功能
的动态链接库,只需把文件内容替换为下面的代码。当然,编译需要boost_python.lib支持,运行需要boost_python.dll支持
。&#include&string&#include &boost/python.hpp&using namespace boost::#pragma comment(lib, "boost_python.lib")std::char const* Recognise(const char* url){&&& strtmp ="从dll中返回的数据... : ";&&& strtmp+=&&& return strtmp.c_str();}BOOST_PYTHON_MODULE(pyUtil){&&& def("Recognise", Recognise);}
可以非常明显地看到,用了boost.python库之后,简单了很多。因为boost.python为你做了很多的事情。。恩。}

我要回帖

更多关于 混编混岗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信