锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置::锐英源 / 英语翻译 / 高级文本编辑器和标尺 / .NET的DLL在x64和Windows7不工作解决方法:P/Invoke参数修改为IntPtr
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

.NET的DLL在x64和Windows7不工作解决方法:P/Invoke参数修改为IntPtr

Hello Aleksei,你好,Aleksei,

First of all, Thanks for your great work. 首先,谢谢你的伟大的工作。

However I try to embed your work in my project which built in X64, unfortunately it doesn't work. 但是我尝试嵌入你的代码在我的项目中,建于X64,不幸的是它不工作。

I debug a little bit, error is caused by the SendMessage which import from USER32. 我调试了一下,错误是从USER32导入的SendMessage函数引起的。

Any idea about it?有没有一些关于它的想法?

Thanks 谢谢。

SendMessage routine is a system one. Sorry, but I was not able to test this control on x64 system. Can you provide me with more info about the error. Which line (or lines) of code cause the exception?
SendMessage是一个系统程序。对不起,我没能在x64系统中测试这个控件,你能为我提供有关错误的更多信息,哪行代码引起的异常?



Hello Alex, 你好,亚历克斯,

Thanks so much for your kindly reply. 非常感谢您亲切的回复。

The error occurs in line 1504 of ExtendedRichTextBox.cs, the last line of set property of SelectionCharStyle. As following:

ExtendedRichTextBox.cs的错误发生在第1504行。SelectionCharStyle的设置属性的最后一行。如下:
SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref param);

The definition of SendMessage defined in line 732:在732行中定义的SendMessage函数的定义:
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern int SendMessage(HandleRef hWnd, int msg, int wParam, ref CHARFORMAT2 lParam);

By the way, I tried to modify the CharSet attribute of DllImport from Auto to Unicode, it failed too. 顺便说一下,我试图从Unicode修改DllImport字符集属性,它也失败了

Thanks again.再次感谢。

I just found it not only doesn't work in X64 platform, but also not work properly in Windows 7, so that I decided to debug it and get rid of the bug.

我发现它不仅在X64平台不工作,在Windows 7也不能正常工作,所以,我决定来调试它,解决bug。

The problem is caused for the structure which passed to SendMessage. To avoid this, I used the way as following:

问题是传递给SendMessage的结构引起的。为了避免这种情况,我使用的方法如下:

Step 1. Modify the extern method definition 步骤1。修改EXTERN方法定义
//[DllImport("user32", CharSet = CharSet.Auto)]
//private static extern int SendMessage(HandleRef hWnd, int msg, int wParam, ref CHARFORMAT2 lParam);

[DllImport("user32", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, Int32 wParam, ref IntPtr lParam);

Step 2. Modify the call to that method, as following: 步骤2。修改调用方法,如下:

//SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref fmt);

GCHandle gch = GCHandle.Alloc(fmt);
IntPtr lParam = GCHandle.ToIntPtr(gch);
SendMessage(new HandleRef(this, Handle), EM_SETCHARFORMAT, SCF_SELECTION, ref lParam);
gch.Free();

It works now in Windows 7 and I assume it should works fine in X64 bit as well. 我认为它现在在Windows 7和X64中都没问题了。

main problem in porting 32 bit code to 64 bit platform and vice versa is the size of pointers, which is 4 bytes in x86 and 8 bytes in x64. So far there is no way for native platforms (like C\C++\Delphi) to produce the code for both platforms other than recompilation with retargeting to new paltform.

主要问题在于32位代码移植到64位平台,反之亦然是指针的大小,也就是在x864个字节和x64的8个字节,到目前为止,没有办法让本地平台(如C\ C++\Delphi)以产生2个平台都支持的文件,只有重新编译且移植,才能支持新平台。

In .NET world it's much easier, due to existence of IntPtr (UIntPtr) which is platform independent and changes accordingly to he underlying pointer size used in end user's system.

在.NET世界中,更容易,因为IntPtr的(UIntPtr)的存在,其相应的是平台独立,且依据在最终用户的系统中使用指针大小来变化。

I have noticed that many P/Invoke declarations are written using Int32 or UInt32 instead of pointers, so did I here (this is my mistake, sorry). This will limit the usage of such code to the 32 bit platforms only as the size of Int32 and UInt32 is 4 bytes (comparing with x64 8 bytes). And of course when you'll try to execute such code you will get memory exception.

我注意到,很多的P / Invoke的声明使用的Int32或UInt32的,而不是指针写的,所以我才在这里(这是我的错,对不起)。这将限制这样的代码到32位平台的使用,仅作为的Int32的大小和UInt32的4个字节(和64平台相比,是8个字节)当然,当你试着执行这样的代码,会出现内存异常

So, the solution is simple. Replace all Int32 and UInt32 parameters in P/Invoke declarations with corresponding pointers from .NET world (IntPtr, UIntPtr, SafeHandle, HandleRef and others).

所以,解决的办法很简单。在与.NET环境(IntPtr的,IntPtr的,SafeHandle的,HandleRef等)对应的指针配套的P/Invoke声明里更换所有的Int32和UInt32的参数。

Hope this info will help someone. Good luck!

希望这个信息会帮助别人。好运!

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内