C++调用其他语言(C#、java、python)

时间:2024-04-03 16:37:57

完整的调用代码见文章末尾。

 

 

 

 

调用C#

1.写一个如下的C#类库

C++调用其他语言(C#、java、python)

 

2.将生成的Add.dll放入c++程序的exe生成目录同级

(运行时使用,这样放就不用把dll放入环境变量或系统目录了)

C++调用其他语言(C#、java、python)

 

3.再将生成的Add.dll放入项目文件目录

(放这里是为了方便代码引用,就不需要配置引用目录或代码中写引用全路径了)

C++调用其他语言(C#、java、python)

 

4.设置项目属性为clr

C++调用其他语言(C#、java、python)

 

5.代码调用

项目支持clr后,就可以在C++代码里用c#的类了

使用using引用c#类库,然后使用using namespace引用其中的命名空间

#using "Add.dll"
using namespace Add;
using namespace System;

 

代码中直接使用c#的类对象,调用add函数(m_num 为C++代码中定义的int型成员变量)

AddNum^ ad = gcnew AddNum();
m_num = ad->add(m_num);

 

 

 

 

调用java

首先需要明确可能遇到的问题。

c++调用java类时需要类的完整包路径,如env->FindClass("java/lang/String");

这里简单点直接文本写完命令行生成class了。

 

如下java代码,生成Substraction.class

C++调用其他语言(C#、java、python)

 

将生成Substraction.class以及java中的jni.h、jni_md.h、jvm.lib放入c++项目文件目录

将java中的jvm.dll加入环境变量path(不能直接放在exe同级目录)

C++调用其他语言(C#、java、python)

 

 

代码中引用头文件和lib

#include "jni.h"
#pragma  comment(lib,"jvm.lib")

 

调用代码如下:(m_num 为C++代码中定义的int型成员变量)

               JavaVMInitArgs vm_args;
memset(&vm_args,0,sizeof(vm_args));
vm_args.version = JNI_VERSION_1_8;//jdk版本
vm_args.nOptions = 1;
JavaVMOption  options[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.options = options;


JNIEnv *env;
JavaVM *jvm;
long status = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
if (status == JNI_ERR) 
{
cout<<"JNI_CreateJavaVM 错误"<<endl;
return;
}




jclass cls = env->FindClass("Substraction");//加载类
if (NULL == cls)
{
cout<<"FindClass 错误"<<endl;
return;
}
jmethodID mid = env->GetStaticMethodID(cls,"substraction","(I)I");//(I)V 表示参数为int,返回值为int
if (0 == mid)
{
cout<<"GetStaticMethodID 错误"<<endl;
return;
}


m_num  = env->CallStaticIntMethod(cls,mid,m_num);


jvm->DestroyJavaVM();

 

 

 

 

 

调用python

这里用的是3.6.3版本

记得把python加入环境变量path

先说一下以下三个坑

 

1.文件名一定不能是test,因为系统模块有一个

 

2.不存在#include <inttypes.h>

屏蔽该行,包含#include <stdint.h>

 

3.没有python36_d.lib

pyconfig.h中:pragma comment(lib,"python36_d.lib")

改为python36.lib

 

 

先写一个python文件MyTestMul.py:定义个add函数

def add(i,j):    

    return i+j

该文件放在生成的exe目录同级

 

 

调用前先包含头文件(头文件挺多,这里就把python的include目录加入工程)

把python36.lib放入项目目录

#include <stdint.h>
#include "Python.h"

C++调用其他语言(C#、java、python)

 

调用代码如下:(m_num 为C++代码中定义的int型成员变量)

               Py_SetPythonHome(L"C:\\py363");

Py_Initialize();
if ( !Py_IsInitialized() ) 
{
cout<<"Py_Initialize 错误"<<endl;
return;
}


PyObject* model = PyImport_ImportModule("MyTestMul");
if (NULL == model)
{
cout<<"PyImport_ImportModule 错误"<<endl;
return;
}

PyObject* pfun = PyObject_GetAttrString(model,"add");


PyObject* pParm = PyTuple_New(2);
PyTuple_SetItem(pParm, 0, Py_BuildValue("i",1000));
PyTuple_SetItem(pParm, 1, Py_BuildValue("i",m_num));


PyObject* pRetVal = PyEval_CallObject(pfun, pParm);
int ret = PyArg_Parse(pRetVal, "i", &m_num); // 从返回值从取出int型返回值  
if (0 == ret)
{
cout<<"PyArg_Parse错误"<<endl;
return;
}

Py_Finalize();

 

 

 

 

 

 

 

 

完整调用代码:

#include <iostream>
using namespace std;

#using "Add.dll"
using namespace Add;
using namespace System;

#include "jni.h"
#pragma  comment(lib,"jvm.lib")

#include <stdint.h>
#include "Python.h"

class Run
{
int  m_num;
public:
Run()
{
m_num = 0;
cout<<"num:"<<m_num<<endl;
cout<<endl<<endl;


Csharp();
java();
python();
}


private:
void Csharp()
{
cout<<"调用C#"<<endl;


AddNum^ ad = gcnew AddNum();
m_num = ad->add(m_num);


cout<<"结果:"<<m_num<<endl;
cout<<endl<<endl;
}
void java()
{
cout<<"java"<<endl;


JavaVMInitArgs vm_args;
memset(&vm_args,0,sizeof(vm_args));
vm_args.version = JNI_VERSION_1_8;//jdk版本
vm_args.nOptions = 1;
JavaVMOption  options[1];
options[0].optionString = "-Djava.class.path=.";
vm_args.options = options;


JNIEnv *env;
JavaVM *jvm;
long status = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
if (status == JNI_ERR) 
{
cout<<"JNI_CreateJavaVM 错误"<<endl;
return;
}




jclass cls = env->FindClass("Substraction");//加载类
if (NULL == cls)
{
cout<<"FindClass 错误"<<endl;
return;
}
jmethodID mid = env->GetStaticMethodID(cls,"substraction","(I)I");//(I)V 表示参数为int,返回值为int
if (0 == mid)
{
cout<<"GetStaticMethodID 错误"<<endl;
return;
}


m_num  = env->CallStaticIntMethod(cls,mid,m_num);




cout<<"结果:"<<m_num<<endl;
cout<<endl<<endl;


jvm->DestroyJavaVM();
}
void python()
{
cout<<"调用python"<<endl;


Py_SetPythonHome(L"C:\\py363");


Py_Initialize();
if ( !Py_IsInitialized() ) 
{
cout<<"Py_Initialize 错误"<<endl;
return;
}




PyObject* model = PyImport_ImportModule("MyTestMul");
if (NULL == model)
{
cout<<"PyImport_ImportModule 错误"<<endl;
return;
}






PyObject* pfun = PyObject_GetAttrString(model,"add");


PyObject* pParm = PyTuple_New(2);
PyTuple_SetItem(pParm, 0, Py_BuildValue("i",1000));
PyTuple_SetItem(pParm, 1, Py_BuildValue("i",m_num));


PyObject* pRetVal = PyEval_CallObject(pfun, pParm);
int ret = PyArg_Parse(pRetVal, "i", &m_num); // 从返回值从取出int型返回值  
if (0 == ret)
{
cout<<"PyArg_Parse错误"<<endl;
return;
}


cout<<"结果:"<<m_num<<endl;
cout<<endl<<endl;


Py_Finalize();
}
};


void main()
{
Run();
}