完整的调用代码见文章末尾。
调用C#
1.写一个如下的C#类库
2.将生成的Add.dll放入c++程序的exe生成目录同级
(运行时使用,这样放就不用把dll放入环境变量或系统目录了)
3.再将生成的Add.dll放入项目文件目录
(放这里是为了方便代码引用,就不需要配置引用目录或代码中写引用全路径了)
4.设置项目属性为clr
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
将生成Substraction.class以及java中的jni.h、jni_md.h、jvm.lib放入c++项目文件目录
将java中的jvm.dll加入环境变量path(不能直接放在exe同级目录)
代码中引用头文件和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"
调用代码如下:(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();
}