这篇文章主要介绍“ c++互调的使用方法”,在日常操作中,相信很多人在 c++互调的使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答” c++互调的使用方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
#if !defined(__CCALLDLL2__)
#define __CCALLDLL2__
#ifdef C_API_EXPORTS
#define C_API_TEST extern __declspec(dllexport)
#else
#define C_API_TEST extern __declspec(dllimport)
#endif // C_API_EXPORTS
#ifdef __cplusplus
extern "C" {
#endif
//#define extern "C" __declspec(dllimport)
struct user
{
int id;
int age;
};
struct structpointer
{
int id;
int* ptrid;
};
typedef void(*cbfun1)(int x, int y);
typedef int(*cbfun2)(int x, int y);
struct alignteststruct
{
int v1;
char v2;
char v3;
int v4;
};
struct alignteststruct2
{
int v1;
char v2;
char* v3;
int v4;
};
struct alignteststruct3
{
int v1;
char v2;
char* v3[3];
int v4;
};
C_API_TEST int say(int u);
C_API_TEST int saystruct(user u);
C_API_TEST int retstruct(user* u, int x, int y);
C_API_TEST user* retstructptr(user* u, int x, int y);
C_API_TEST void setstructs(user u[], int len, int x, int y);
C_API_TEST void processstructpointer(structpointer *sp);
C_API_TEST void processstructpointer2(structpointer *sp, int len);
C_API_TEST void cbfundemo(user* u, int x, int y, cbfun1 cb);
C_API_TEST int cbfundemo2(user* u, int x, int y, cbfun2 cb);
C_API_TEST void dispalign(alignteststruct ats);
C_API_TEST void dispalign2(alignteststruct2 ats);
C_API_TEST void dispalign3(alignteststruct3 ats);
C_API_TEST void dispalign4(alignteststruct3 ats, int v3len);
C_API_TEST void xxxByReference(char* c1, short* s1, int* i1, long* l1, float* f1, double* d1);
C_API_TEST char* strtocharptr(char* arg);
C_API_TEST void deletepr();
C_API_TEST int globalvar; //public Pointer getGlobalVariableAddress(java.lang.String symbolName)
C_API_TEST char * test1();
C_API_TEST char * test2();
#ifdef __cplusplus
}
#endif
#endif
// ccalldll2.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include <iostream>
//#using "cSharpDLLforJNA.dll"
using namespace System;
using namespace cSharpDLLforJNA;
using namespace std;
//#pragma data_seg("MyData") //没效果
int globalvar=58; //public Pointer getGlobalVariableAddress(java.lang.String symbolName)
//#pragma data_seg()
//https://www.cnblogs.com/luzhiyuan/p/3947576.html 中提到extern int g_nTest;和extern int _declspec(dllimport) g_nTest;
//如果不用_declspec(dllimport)则代表的是地址,如果用到了则代表的是真实的变量 如果这样的话,那可不可以用于hacker
int say(int u)
{
/*gcnew User();*/
Main ^dllmain = gcnew Main();
user user;
user.age = 20;
user.id = 1;
int r = dllmain->say(u);
return r;
}
int saystruct(user u)
{
int r = u.id + u.age;
return r;
}
int retstruct(user* u,int x,int y)
{
//直接在u上处理然后返回这个u,那么在java中原来的参数user与返回的user应该id/age都相同了,做实验看看
u->id += 10 + x;
u->age += 10 + y;
return 0;
}
user* retstructptr(user* u, int x, int y)
{
//直接在u上处理然后返回这个u,那么在java中原来的参数user与返回的user应该id/age都相同了,做实验看看
u->id += 20 + x;
u->age += 20 + y;
cout << "cpp_u->id=" << u->id << " u->age=" << u->age << endl;
return u;
}
void setstructs(user u[], int len,int x, int y)
{
//int len = sizeof(u) / (2 * sizeof(int)); //不正确的做法,实验发现传入3个(????)打印显示为1????
cout << "cpp_len=" << len << endl;
for (int i = 0; i < len; i++)
{
u[i].id = x+i;
u[i].age = y+i;
cout << i<<":id=" << u[i].id << " age=" << u[i].age << endl;
}
}
void processstructpointer(structpointer *sp)
{
if (sp == NULL)
return;
int* p;
p = sp->ptrid;
/*for (int i = 0; i < len; i++)
{*/
//p = (sp + i)->ptrid;
while (true)
{
if (*p != 0)
{
cout << *p << endl;
*p += 1;
p += 1;
}
else
{
break;
}
}
//}
}
void processstructpointer2(structpointer *sp,int len)
{
if (sp == NULL)
return;
int* p;
//p = sp->ptrid;
for (int i = 0; i < len; i++)
{
p = (sp + i)->ptrid;
cout << ">>>>>>>>>>>>" << endl;
while (true)
{
if (*p != 0)
{
cout << *p << endl;
*p += 1;
p += 1;
}
else
{
break;
}
}
}
}
void cbfundemo(user* u, int x, int y, cbfun1 cb)
{
u->id += x;
u->age += y;
cb(u->id, u->age);
}
int cbfundemo2(user* u, int x, int y, cbfun2 cb)
{
u->id += x;
u->age += y;
return cb(u->id, u->age);
}
void dispalign(alignteststruct ats)
{
cout << "dispalign=>"<<ats.v1 << ":" << ats.v2 << ":" << ats.v3 << ":" << ats.v4 << endl;
}
void dispalign2(alignteststruct2 ats)
{
cout << "dispalign=>" << ats.v1 << ":" << ats.v2 << ":" << ats.v3 << ":" << ats.v4 << endl;
}
void dispalign3(alignteststruct3 ats)
{
char (*p)[3] = (char (*)[3])ats.v3; //常量下标,如果是变量下标则ERROR
//char *pp[3] = (char (*)[3])ats.v3;
int line = sizeof(ats.v3) / sizeof(ats.v3[0]);
cout << "line=" << line << endl;
cout << "dispalign3==>" << ats.v1 << ":" << ats.v2 << ":" << ats.v3 << ":" << ats.v4 << endl;
}
void dispalign4(alignteststruct3 ats, int v3len)
{
//char(*p)[len] = (char(*)[len])ats.v3;
//char *p[] = new char
}
void xxxByReference(char* c1, short* s1, int* i1, long* l1, float* f1, double* d1)
{
cout << "xxxByReference" << *c1 << ":" << *s1 << ":" << *i1 << ":" << *l1 << ":" << *f1 << ":" << *d1 << endl;
*c1 += 1;
*s1 += 1;
*i1 += 1;
*l1 += 1;
*f1 += 1;
*d1 += 1;
globalvar += 1;
}
char* pr;
char* strtocharptr(char* arg)
{
cout << "strtocharptr==>" << arg << endl;
arg[1] += 1;
cout << "strtocharptr2==>" << arg << endl;
pr = (char*)malloc(1000000);
memset(pr, 0, 1000000);
int len = strlen(arg);
memcpy(pr, arg, len);
pr[len] = 'o';
pr[len + 1] = 'k';
return pr;
}
void deletepr()
{
if (pr != NULL)
free(pr);
pr = NULL;
}
char* pt;
char * test1(){
pt = (char*)malloc(200000000);
char buf[100] = "hello你world";
memcpy(pt, buf, 100);
return pt;
}
char * test2(){
if (pt != NULL)
{
free(pt);
cout << "free(pt)" << endl;
}
else
cout << "no free" << endl;
char* p = "helloworld你好,delete pt:";
cout << sizeof(p) << ":"<<sizeof("helloworld你好,delete pt:") <<endl; //8:26
return "helloworld你好,delete pt:";
}
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE 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:
break;
}
return TRUE;
}
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
//using System.Threading.Tasks;
namespace cSharpDLLforJNA
{
public class Main
{
//public struct user
//{
// public int id;
// //public string name;
// public int age;
//}
//public void sayuser(user user)
//{
// //Console.WriteLine(user.name + ":id=" + user.id + " age=" + user.age);
// Console.WriteLine( "id=" + user.id + " age=" + user.age);
//}
public int say(int i)
{
Console.WriteLine("i=" + i);
return i + 1;
}
}
}
主c#程序的按钮点击事件及相关代码:
[DllImport("ccalldll2.dll", EntryPoint = "retstruct",CallingConvention=CallingConvention.Cdecl)]
public static extern int retstruct(IntPtr ptrUser, int x, int y); //在引用中只引用了ccalldll2,而ccalldll2又用到了cSharpDLLforJNA,这样有问题吗
//[DllImport("cSharpDLLforJNA.dll", EntryPoint = "say", CallingConvention = CallingConvention.Cdecl)]
//public static extern int saybak(int i); //在引用中只引用了ccalldll2,而ccalldll2又用到了cSharpDLLforJNA,这样有问题吗
[StructLayout(LayoutKind.Sequential)]
struct user
{
public int id;
public int age;
};
[DllImport("ccalldll2.dll", EntryPoint = "say", CallingConvention = CallingConvention.Cdecl)]
public static extern int say1(int u);
private void btnInptr_Click(object sender, EventArgs e)
{
user u = new user();
u.id = 5;
u.age = 7;
//先要通过Marshal来分配内存空间,根据user的大小进行分配非托管空间大小
int size = Marshal.SizeOf(u);//对于值类型,可以Sizeof(变量),对于引用类型则Sizeof(typeof(TYPE))
IntPtr ptruser = Marshal.AllocHGlobal(size);//分配内存
//将u的值copy到ptruser空间
Marshal.StructureToPtr(u, ptruser, false);
int res = retstruct(ptruser, 5, 5);//调用DLL中函数 retstruct中将对ptruser指针所指的user中的id和age处理
user u2 = (user)Marshal.PtrToStructure(ptruser, typeof(user));//将处理之后的ptruser再转换为user
Console.WriteLine(u2.id + ":" + u2.age);
Console.WriteLine(res+":"+u.id+":"+u.age);
Marshal.FreeHGlobal(ptruser);
Console.WriteLine(new Main().say(2));
Console.WriteLine("say=" + say1(3));
}
显示如下:
20:22
0:5:7
i=2
3
i=3
say=4
其实就是cSharpDLLforJNA是c#做的dll,ccalldll2是c++,并且在其中调用了cSharpDLLforJNA.dll中函数,然后主程序中直接调用了SharpDLLforJNA中的函数(通过引用导入dll,代码中用using cSharpDLLforJNA即可),主程序中还调用了ccalldll2.dll中的say函数,这个say还调用了SharpDLLforJNA中的函数。
到此,关于“ c++互调的使用方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/2963604/blog/5013940