c++互调的使用方法
发表于:2024-11-16 作者:千家信息网编辑
千家信息网最后更新 2024年11月16日,这篇文章主要介绍" c++互调的使用方法",在日常操作中,相信很多人在 c++互调的使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答" c++互调的使用方法"的疑惑
千家信息网最后更新 2024年11月16日c++互调的使用方法
这篇文章主要介绍" 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//#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)则代表的是地址,如果用到了则代表的是真实的变量 如果这样的话,那可不可以用于hackerint 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 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) << ":"< 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++互调的使用方法"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
函数
方法
c++
使用方法
处理
学习
你好
变量
程序
空间
问题
分配
实验
相同
下标
主程序
代码
代表
内存
参数
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
汽车销售系统数据库模板下载
金蝶采购入库数据库表
境内服务器托管能给境外吗
邮编数据库
软件开发项目收尾意向书
查询数据库驱动语句
网络技术教程pdf版
组织部党员数据库系统
云服务器标准型和轻量型哪个好
上海复高软件开发公司怎么样
维护网络安全要加强
荒野行动哪个服务器有高级武器
单片机用什么软件开发
设计与网络安全需求
大医医学数据库
武汉 万户网络技术有限公司
达州网络技术要多少钱
清楚sql表中所有数据库
南通网络安全准入控制供应商
小妖精美化软件开发
tp如何连接多个数据库
金蝶采购入库数据库表
王树彤谈互联网科技
万方数据库的主题词
联想服务器厂家服务至上
p6数据库连接
河北坤柔网络技术
软件开发新技术期末考试
成人大学网络安全专业
如何便捷给云服务器传资料