[英]Creating a basic C++ .dll for p/invoke in C#
我是一名C#程序员,不幸的是由于年龄和经验,我没有机会在我的学习中有机会完成编程的C ++时代 - 这对我来说是多么神秘和新鲜。 这里并没有真正讨论学习这种与否的重要性,但我需要一些应该是一件小事的帮助。
我需要帮助将我的C ++代码打包成.dll。 我没有使用C ++的经验,并且我很难创建一个可以从( Visual Studio 2010 )调用的.dll。 请继续阅读以获取更多详细信息以及我要打包的代码。
我有一些代码需要在非托管环境中运行。 在正常情况下,简单的p / invoke适用于此任务。 连接一些[ImportDll]
,你很高兴。 最糟糕的情况我有时可以使用编组。 然而,由于我还没有真正发现的原因,我目前的任务似乎不可能。
我试图从旧的非托管C ++应用程序owner drawn list box
的owner drawn list box
读取一些数据,并从中获取文本。 我已经看到了几个如何执行此操作的示例 - 但它们是旧的VB6代码。
我发现了C ++等价物,但这对我来说也不合适。 即使使用p / invoke,内存的移动以及它需要如何操作似乎也会遇到很多麻烦。 这个过程非常简单。
我需要创建一个简单的C ++ .dll来运行我在非托管代码中需要的方法,并使用结果填充变量。
虽然这听起来很蠢,但我不知道该怎么做 。 我试过在Visual Studio中运行简单的C ++向导(使用Visual Studio 2010),我只是没有运气。 我希望有人可以帮我解决这个问题,也许可以解释一下发生了什么,这样我就可以从中学习。
这是我需要放入.dll
的代码。
目的是让hListWnd
在C#中作为IntPtr
传递, index
将是一个简单的Int32
,并且outputResult
将转到任何必要的东西以使其工作。 在其他p / invoke情况下,我已经看到使用System.Text.StringBuilder
完成此操作,但我愿意使用任何东西来使这项工作正常。
void GetListItemData( HWND hListWnd, long index, char *outputResult )
{
int result;
DWORD processID;
HANDLE hProcess;
char *itemData;
char sDataRead[5];
DWORD bytes;
DWORD lListItemHold, lListItemDataHold;
*outputResult=0;
if( hListWnd )
{
GetWindowThreadProcessId( hListWnd, &processID );
hProcess=OpenProcess( 0x10|0xf0000|PROCESS_VM_READ, 0, processID );
if( hProcess )
{
lListItemHold=(DWORD)SendMessage( hListWnd, LB_GETITEMDATA, index-1, 0 );
lListItemHold=lListItemHold+24;
result=ReadProcessMemory( hProcess, (void *)lListItemHold, &sDataRead, 4, &bytes );
if( !result )
{
RaiseWinErr();
}
memcpy( &lListItemDataHold, &sDataRead, 4 );
lListItemDataHold=lListItemDataHold+6;
ReadProcessMemory( hProcess, (void *)lListItemDataHold, outputResult, 16, &bytes );
CloseHandle( hProcess );
}
}
}
如果有人可以帮助我,拜托,我在这里乞讨。 这对我来说已成为一个非常令人沮丧的问题。 我试图使用RtlMoveMemory
和ReadProcessMemory
p / invoke在C#中重现这一点,但无济于事。 我一直在寻找日子和日子,并继续拿出死的结果。 我知道有些代码没有多大意义(我有人问我为什么需要+6
和+24
是什么等等),绝对的事实是我并不完全知道。 我所知道的是所有者绘制列表框上有一些图形,这些偏移的目的是检查绘制图形区域之外的数据,因为List Item
的实际结构是未知的。
我尝试过的另一种方法是使用Accessibility.dll
库将我的项目检索为IAccessible
。 这也证明没有结果。 我也尝试过ManagedWinApi
的ManagedWinApi,那里的图书馆没有任何成功。
我知道这段代码有效。 它只是在C#中不起作用。 我的理论是使用[DllImport]
在C#中调用它会给我想要的结果。
再次感谢任何人提供的帮助。
第三个参数需要是一个byte [],编组为char *,大小为16。
如果检查ReadProcessMemory的文档,它需要一个缓冲区和一个大小,并且此函数将大小传递为16个字节。 这意味着您将需要一个16字节的数组。 运行时应该非常乐意编组一个大小为16的byte []。注意不要将C ++ char与C#char混合使用 - C#char实际上是Windows上的C ++ wchar_t。 C ++ char是C#的字节。
并不是说我对这些函数的工作方式有任何实际的想法 - 我只是跟踪了第三个参数的用法,它实际上只传递给了ReadProcessMemory,其参数清楚地记录在案。
要打包成.dll(假设你没有其他内容可以进入.dll),你想在开头添加一些东西,要求C ++编译器不要破坏名称并为你导出它,产生这个作为第一线
extern "C" __declspec(dllexport) void GetListItemData( HWND hListWnd, long index, char *outputResult )
您只需要一个C ++源文件,没有标题,并编译为DLL(它在项目设置中)。 除了函数和任何您需要的包含之外,您不需要任何代码。
在C#中
[System.Runtime.InteropServices.DllImport(
DLLPath,
CallingConvention = CallingConvention.Cdecl
)]
private static extern void GetListItemData(
System.IntPtr hWnd,
System.Int32 index,
[MarshalAs(UnmanagedType.LPArray)]byte[] buffer
);
不幸的是,您可以确保缓冲区的大小足够。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.