怎样向C++编写的DLL中向python脚本传递参数数

其他回答(1)
将这个复杂格式用C/C++简化写一个方法(易于C#调用的方法),然后由C#调用
&&&您需要以后才能回答,未注册用户请先。查看: 107|回复: 2
咨询一个易语言调用C++编写的DLL参数
阅读权限10
结帖率: (1/2)
我用C++写了一个dll& &用处是把参数2传递到参数一加密,最后要输出参数一,小白一枚,始终输出不了参数一的加密数据
这个C++的类型也不知道在的dll面板写什么类型,求救,帮帮忙吧 能帮忙的给个几十一百幸苦费都可以,已经通宵2天2夜弄这个了,实在不行了,来这里求教,
21:06 上传
点击文件名下载附件
4.57 KB, 下载次数: 7
C++编写dll
(2.37 KB, 下载次数: 0)
21:03 上传
.局部变量 strDest, 字节集
.局部变量 Source, 字节集
Source = { 49, 0, 50, 0, 51, 0, 0, 0 }
' Unicode的 123
编码_ANSI到UNICODE("123")
strDest = 取空白字节集 (1024)
信息框 (SimpleEncrypt (strDest, Source), 0, , )
输出调试文本 (编码_Unicode到ANSI (strDest))
补充内容 ( 21:48):
编码_Unicode到ANSI
编码_ANSI到UNICODE
之类的命令自己找 ...
回答提醒:如果本帖被关闭无法回复,您有更好的答案帮助楼主解决,请发表至
可获得加分喔。友情提醒:本版被采纳的主题可在
帖子申请荣誉值,获得 1点 荣誉值,荣誉值可兑换终身vip用户组哦。快捷通道: →
阅读权限130
结帖率: (26/26)
&&strDest字节集&&Source字节集&&Source = { 49, 0, 50, 0, 51, 0, 0, 0 }&&' Unicode的 123&&编码_ANSI到UNICODE(&123&)strDest = 取空白字节集 (1024)信息框 (SimpleEncrypt (strDest, Source), 0, , )输出调试文本 (编码_Unicode到ANSI (strDest)).版本 2
.局部变量 strDest, 字节集
.局部变量 Source, 字节集
Source = { 49, 0, 50, 0, 51, 0, 0, 0 }&&' Unicode的 123&&编码_ANSI到UNICODE(&123&)
strDest = 取空白字节集 (1024)
信息框 (SimpleEncrypt (strDest, Source), 0, , )
输出调试文本 (编码_Unicode到ANSI (strDest))
wchar&&宽字符
补充内容 ( 21:48):
编码_Unicode到ANSI& &&&编码_ANSI到UNICODE& &之类的命令自己找一下& &各路模块都有.
热心帮助他人,荣誉+1,希望继续努力(*^__^*) 嘻嘻!
您可以选择打赏方式支持他
阅读权限155
签到天数: 13 天结帖率: (4/4)
&&SimpleEncrypt逻辑型&SimpleEncrypt.dllSimpleEncryptap整数型√&bp整数型&&.版本 2
.DLL命令 SimpleEncrypt, 逻辑型, &SimpleEncrypt.dll&, &SimpleEncrypt&
& & .参数 ap, 整数型, 传址
& & .参数 bp, 整数型
&&_按钮1_被单击&&ap整数型&&bp整数型&&a文本型&&b文本型&&a = “”b = “1”ap = 取淞渴莸刂 (a)bp = 取淞渴莸刂 (b)调试输出 (SimpleEncrypt (ap, bp))调试输出 (指针到文本 (ap))spec特殊功能支持库
.版本 2
.支持库 spec
.子程序 _按钮1_被单击
.局部变量 ap, 整数型
.局部变量 bp, 整数型
.局部变量 a, 文本型
.局部变量 b, 文本型
b = “1”
ap = 取变量数据地址 (a)
bp = 取变量数据地址 (b)
调试输出 (SimpleEncrypt (ap, bp))
调试输出 (指针到文本 (ap))
开始运行被调试程序
* “荺?糎?袪Y鲜=?J,”
但最后报错
您可以选择打赏方式支持他
精易论坛 - 有你更精彩 /1
支持作者开源,请积极给优秀源码评分
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
揭阳精易科技有限公司申明:我公司所有的培训课程版权归精易所有,任何人以任何方式翻录、盗版、破解本站培训课程,我们必将通过法律途径解决!
公司简介:揭阳市揭东区精易科技有限公司致力于易语言教学培训/易语言学习交流社区的建设与软件开发,多年来为中小企业编写过许许多多各式软件,并把多年积累的开发经验逐步录制成视频课程供学员学习,让学员全面系统化学习易语言编程,少走弯路,减少对相关技术的研究与摸索时间,从而加快了学习进度!
防范网络诈骗,远离网络犯罪
违法和不良信息举报电话,QQ: ,,邮箱:@
Powered by
粤公网安备 2524252627282345678910111213141516171819202122232425262728293031123456
阅读排行榜
评论排行榜一、C\C++ 运行时库编译选项简单说明
问题:我的dll别人没法用
运行时库是个很复杂的东西,作为开发过程中dll制作需要了解的一部分,这里主要简单介绍一下如何选择编译选项。
在我们的开发过程中时常会遇到这样的问题:
1. 我的VS版本比较高(比如:VS2012),我想制作一个dll,封装了几个函数给别人用。
2. 打包后发现我的dll引用了msvcr110.dll或者msvcr110d.dll,这个dll别人电脑可能没有。
3. 于是别人使用时出现了诸如:“无法在DLL“XXXX.dll”中找到名为“XXXX()”的入口点”等问题。
最终结果就是,反复检查发现都没有错,用工具查看也发现函数确实已经导出了,但是别人就没法用。
这里可能就需要对编译选项进行修改了。
解释:如何避免上述问题
在VS中打开:项目属性——&配置属性——&C/C++——&代码生成——&运行时。其中可以看到多个选项,如下图所示:
在微软的msdn中对CRT库进行了简单解释:
下面是我黏贴的表格:
使应用程序使用运行时库的多线程并特定于 DLL 的版本。定义 _MT 和 _DLL,并使编译器将库名 MSVCRT.lib 放入 .obj 文件中。
用此选项编译的应用程序静态链接到 MSVCRT.lib。该库提供允许链接器解析外部引用的代码层。实际工作代码包含在 MSVCR80.DLL 中,该库必须在运行时对于与 MSVCRT.lib 链接的应用程序可用。
当在定义了 _STATIC_CPPLIB (/D_STATIC_CPPLIB) 的情况下使用 /MD 时,它将导致应用程序与静态多线程标准 C++ 库 (libcpmt.lib) 而非动态版本 (msvcprt.lib) 链接,同时仍通过 msvcrt.lib 动态链接到主 CRT。
定义 _DEBUG、_MT 和 _DLL,并使应用程序使用运行时库的调试多线程并特定于 DLL 的版本。它还使编译器将库名 MSVCRTD.lib 放入 .obj 文件中。
使应用程序使用运行时库的多线程静态版本。定义 _MT 并使编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便链接器使用 LIBCMT.lib 解析外部符号。
定义 _DEBUG 和 _MT。此选项还使编译器将库名 LIBCMTD.lib 放入 .obj 文件中,以便链接器使用 LIBCMTD.lib 解析外部符号。
创建 DLL。
将 /DLL 选项传递到链接器。链接器查找 DllMain 函数,但并不需要该函数。如果没有编写 DllMain 函数,链接器将插入返回 TRUE 的DllMain 函数。
链接 DLL 启动代码。
如果命令行上未指定导出 (.exp) 文件,则创建导入库 (.lib);将导入库链接到调用您的 DLL 的应用程序。
将 解释为命名 DLL 而不是 .exe 文件;默认程序名成为 basename.dll 而不是 basename.exe。
除非显式指定 /MD,否则将暗指 /MT。
  创建调试 DLL。定义 _MT 和 _DEBUG。
就从VS的dll库的编译选项来说就前面四项,/MD、/MDd、/MT和/MTd。其中/MDd、/MTd后面的“d”表示编译生成的是Debug版本,也就是用于编译生成Debug版本的程序;不加“d”表示是Release版本的程序,如果此时你把项目配置成Debug版本,编译会不通过。
动态链接多线程库(MD/MDd)
动态链接的运行时库,此时将msvcrt.lib安置到obj文件中,它连接到dll的方式是静态链接,实际上工作的库是msvcrxx.dll。所有的 C 库函数保存在动态链接库 msvcrXX.dll中, 由msvcrXX.dll处理多线程问题。也就是说,这种编译方式下我们是通过msvcrXX.dll这个动态链接库去链接CRT。
此时我们编译的dll引用了msvcrXX.dll文件,这个文件在使用的时候必须能够被计算机查询到。比如:我的电脑编译引用了msvcr110.dll,那么我的dll给别人调用的时候,对方计算机一定要有msvcr110.dll,否则dll库就无法使用。因此这种编译方式,必须将msvcr110.dll一同携带过去,并且要在对方计算机上进行注册。
使用此方式编译时,使用Depends查看,我们可以看到dll 引用了msvcr110.dll,如下图:
静态链接多线程库(MT/MTd)
静态链接多线程库,此时编译器把LIBCMT.lib 安置到OBJ文件中,让链接器使用LIBCMT.lib 处理外部符号。这种方式说简单点就是让我们的dll能够直接链接到CRT,无需引用msvcrXX.dll这个动态链接库。这样我们就不需要担心对方电脑是否拥有对应版本的msvcrXX.dll,因此这是一种方便的好办法。
在这种方式下,编译的dll通过Depends查看就是这样的:
注意:几个注意点
光从上面来看,MT的方式很好用,但是必须要注意一个问题:
不要混合使用库的静态版本和动态版本。在一个进程中有多个库副本会导致问题,因为副本中的静态数据不与其他副本共享。(还应该避免在一个进程中混合使用这些库的调试版本和非调试版本)。
还有,在实际使用中能用MD就用MD的方式,因为这种方式软件更小,调用同一个dll时在内存中使用的是同一个副本。这就不会有堆空间释放问题:
不同的模块各自有一份C运行时库代码,各个C运行库会有各自的堆,导致了各个模块会有各自的堆。如果在A堆中申请空间,到B堆中释放就会有崩溃,在模块A申请的空间,必须在模块A中释放。
二、函数调用方式_cdecl与_stdcall的选择
_stdcall调用
_stdcall是Pascal程序的缺省调用方式,参数采用从右到左的压栈方式,被调函数自身在返回前清空堆栈。形式如下:
#define SW_REV extern &C& _declspec(dllexport)
SW_REV int __stdcall add(int a, int b);
__stdcall add(int a, int b)
return a+b;
_cdecl调用
_cdecl是C/C++的缺省调用方式,参数采用从右到左的压栈方式,传送参数的内存栈由调用者维护。_cedcl约定的函数只能被C/C++调用,每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。
在不加修饰的情况下,VC++默认使用这种调用方式,形式如下(默认,可省略):
#define SW_REV extern &C& _declspec(dllexport)
SW_REV int add(int a, int b);
int add(int a, int b)
return a+b;
什么时候区分?
其实两种方式都一样,区别在于调用。例如:有些语言要求调用时只认_stdcall,那么就只能按照要求使用_stdcall版本的dll。很多情况下,调用方式都可选择,说白了,就是一定要保持一致,例如C#调用上述_stdcall方式的dll:
[DllImport(&SwLib.dll&, EntryPoint = &add&, CallingConvention = CallingConvention.StdCall)]
private static extern int add(int a, int b);
这里CallingConvention需要选择CallingConvention.StdCall,如果我将其改成 CallingConvention.Cdecl,程序就会报错,指出堆栈调用不对称:
PS:写这个东西真的好费劲,上次写到现在好久了,有好多想记录一下的东西,发现自己懒得写,好懒!
阅读(...) 评论()1. 如果函数只有传入参数,比如:
int__declspec(dllexport) test(constint N)
return N+10;
对应的C#代码为:
[DllImport("test.dll", EntryPoint = "#1")]
publicstaticexternint test(int m);
privatevoid button1_Click(object sender, EventArgs e)
textBox1.Text= test(10).ToString();
2. 如果函数有传出参数,比如:
void__declspec(dllexport) test(constint N, int& Z)
对应的C#代码:
[DllImport("test.dll", EntryPoint = "#1")]
publicstaticexterndouble test(int m, refint n);
privatevoid button1_Click(object sender, EventArgs e)
int N = 0;
test1(10, ref N);
textBox1.Text= N.ToString();
3. 带传入数组:
void__declspec(dllexport) test(constint N, constint n[], int& Z)
for (int i=0; i&N; i++)
[DllImport("test.dll", EntryPoint = "#1")]
publicstaticexterndouble test(int N, int[] n, refint Z);
privatevoid button1_Click(object sender, EventArgs e)
int N = 0;
n = newint[10];
for (int i = 0; i & 10; i++)
test(n.Length, n, ref N);
textBox1.Text= N.ToString();
4. 带传出数组:
C++不能直接传出数组,只传出数组指针,
void__declspec(dllexport) test(constint M, constint n[], int *N)
for (int i=0; i&M; i++)
N[i]=n[i]+10;
对应的C#代码:
[DllImport("test.dll", EntryPoint = "#1")]
publicstaticexternvoid test(int N, int[] n, [MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)] int[] Z);
privatevoid button1_Click(object sender, EventArgs e)
int N = 1000;
int[] n, Z;
n = newint[N];Z = newint[N];
for (int i = 0; i & N; i++)
test(n.Length, n, Z);
for (int i=0; i&Z.L i++)
textBox1.AppendText(Z[i].ToString()+"n");
这里声明函数入口时,注意这句 [MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)] int[] Z
在C#中数组是直接使用的,而在C++中返回的是数组的指针,这句用来转化这两种不同的类型.
关于MarshalAs的参数用法以及数组的Marshaling,可以参见这篇转帖的文章:
阅读(...) 评论()

我要回帖

更多关于 向线程传递参数 的文章

 

随机推荐