求助:C#读取C++的函数返回值,struct,char[]?

干巴猴儿 2012-06-25 05:08:58
C++的dll,用来监控注册表的修改,C++的窗口程序可以接收,读取到PARAMS结构体监控信息。
在C#中要怎么写才能接受到信息呢
附:完整的项目源代码:
http://download.csdn.net/detail/tongiii/4392018


struct PARAMS
{
DWORD PID;
HKEY hKey;
char buffer1[1024];
int cbBuffer1;
char buffer2[1024];
int cbBuffer2;
DWORD type;
long result;
};

DETOUR_TRAMPOLINE(LONG WINAPI Real_RegSetValueExW(HKEY, LPCWSTR, DWORD, DWORD, CONST BYTE*, DWORD), RegSetValueExW);
LONG WINAPI Mine_RegSetValueExW(
HKEY hKey,
LPCWSTR lpValueName,
DWORD Reserved,
DWORD dwType,
CONST BYTE* lpData,
DWORD cbData
)
{
LONG nRet;
__try{
nRet = Real_RegSetValueExW(hKey, lpValueName, Reserved, dwType, lpData, cbData);
if(!HOOK_RegSetValueEx)
return nRet;
if(GetCurrentProcessId() == ExplorerPID)
return nRet;
if(GetCurrentProcessId() == RegMonPID)
return nRet;
if((PID == 0) || ((GetCurrentProcessId() == PID) && (PID>0)) )
{
if(lpValueName == NULL || lpData == NULL)
return nRet;
COPYDATASTRUCT data;
PARAMS params = {0};
params.PID = GetCurrentProcessId();
params.hKey = hKey;
memcpy(params.buffer1, lpValueName, wcslen(lpValueName)*2);
params.cbBuffer1=wcslen(lpValueName)*2;
params.type = dwType;
if(cbData>1024)
{
memcpy(params.buffer2, lpData, 1024);
params.cbBuffer2 = 1024;
}
else
{
memcpy(params.buffer2, lpData, cbData);
params.cbBuffer2 = cbData;
}
params.result = nRet;

data.cbData = sizeof(PARAMS);
data.lpData = ¶ms;
data.dwData = TYPE_RegSetValueExW;
SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&data);
}
}__finally{
};
return nRet;
}




下面是C#的winform接收消息的代码,请问,怎么写才能从结构体中取得注册表监控的详细信息呢(修改的键值,修改值)?

const int WM_COPYDATA = 0x004A;
const int WM_CANCELJOURNAL = 0x004B;
public struct PARAMS
{
[MarshalAs(UnmanagedType.U4)]
public uint PID;
public IntPtr hKey; //?指针
public IntPtr buffer1;
//public string buffer1; //指针
public IntPtr cbBuffer1;
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
public IntPtr buffer2;

//public IntPtr buffer2; //指针
public IntPtr cbBuffer2;
public IntPtr type;
public long result;
};
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public PARAMS lpData;
}


protected override void DefWndProc(ref Message m)
{

switch (m.Msg)
{
case WM_COPYDATA:
try
{
COPYDATASTRUCT s = new COPYDATASTRUCT();
Type t = s.GetType();

s = (COPYDATASTRUCT)m.GetLParam(t);

Console.WriteLine("s.cbData:" + s.cbData);
Console.WriteLine("s.dwData:" + s.dwData);

Console.WriteLine("hKey:" + Marshal.ReadInt32(s.lpData.hKey));
Console.WriteLine("PID:" + s.lpData.PID);
Console.WriteLine("type:" + s.lpData.type);
Console.WriteLine("cbBuffer1:" + s.lpData.cbBuffer1);
Console.WriteLine("cbBuffer2:" + s.lpData.cbBuffer2);

PARAMS p = s.lpData;
}
catch (Exception ex) { }
break;
default:
base.DefWndProc(ref m);
break;
}
}

...全文
348 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
luohegongmin 2013-05-24
  • 打赏
  • 举报
回复
有调通后的代码么?下了你的源码, 一直调不通。 我这边有一个需求和你的一样,但在C#使用一会挂不上钩子,拿不到监控的信息。 有调通的代码的话,麻烦楼主给发一个 zelijin@163.com
干巴猴儿 2012-06-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

试试这样

[/Quote]

好使,有效果了。

首先public StringBuider buffer1;这个不行,
然后结构定义中我改成下面
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
public byte[] buffer1;

取值时:如下。
string buffer1= Encoding.Unicode.GetString(p.buffer1);
buffer1 = buffer1.Trim('\0');
Console.WriteLine(buffer1.Length );
Console.WriteLine("Buffer1:" + buffer1);


这样就正确的得到了修改的项目值。


干巴猴儿 2012-06-27
  • 打赏
  • 举报
回复
整个项目的代码:
http://download.csdn.net/detail/tongiii/4392018
哪个高手有兴趣,帮帮忙调试一下看。如能解决,加分感谢!
干巴猴儿 2012-06-27
  • 打赏
  • 举报
回复
这个情况比较特殊。
我用SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&data);
从C++的dll给C#的winform程序传递消息。(原始代码都是C++的dll向mfc的窗口传递消息,能正常接收到。)
传递的消息内容是
struct PARAMS
{
DWORD PID;
HKEY hKey;
char buffer1[1024];
int cbBuffer1;
char buffer2[1024];
int cbBuffer2;
DWORD type;
long result;
};
这样一个结构体。
在C#项目中,
现在能正确得到PID,其他的都不对。通过调试程序,感觉得到的内容好像是指针。不知道应该如何能获得我真证想要的数据??

最后顶一次帖,如果还是没人能帮忙解决,我就放弃,不弄了。嗨!


ParanoidKing 2012-06-27
  • 打赏
  • 举报
回复
试试这样

const uint WM_COPYDATA = 0x004A;
const uint WM_CANCELJOURNAL = 0x004B;
public struct PARAMS
{
public uint PID;
public IntPtr hKey;
public StringBuider buffer1;
public int cbBuffer1;
public StringBuider buffer2;
int cbBuffer2;
public uint type;
public int result;
};

public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}

protected override void DefWndProc(ref Message m)
{

switch (m.Msg)
{
case WM_COPYDATA:
try
{
COPYDATASTRUCT s = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
PARAMS p = (PARAMS)Marshal.PtrToStructure(s.lpData, typeof(PARAMS));

Console.WriteLine("s.cbData:" + s.cbData.ToInt32());
Console.WriteLine("s.dwData:" + s.dwData);

Console.WriteLine("hKey:" + p.hKey.ToInt32());
Console.WriteLine("PID:" + p.PID);
Console.WriteLine("type:" + p.type);
Console.WriteLine("cbBuffer1:" + p.cbBuffer1.ToString());
Console.WriteLine("cbBuffer2:" + p.cbBuffer2.ToString());
}
catch (Exception ex) { }
break;
default:
base.DefWndProc(ref m);
break;
}
}
干巴猴儿 2012-06-26
  • 打赏
  • 举报
回复
转码也不行的,仍然是乱码
经过一天的调试。有了一点进展:
发现C++的DWord类型 PID中保存的不是真证要取的值,而是一个指针。结构定义,做如下修改。
IntPtr PID;
IntPtr hKey;
然后取值时,使用Marshal.PtrToStructure,
int id = (int)Marshal.PtrToStructure(s.lpData.PID, typeof(int));
终于得到了真证的ProccessID.
buffer1仍然不确定究竟什么样的值,如何获取。
__天涯寻梦 2012-06-25
  • 打赏
  • 举报
回复
转码
Encoding.Unicode.GetString(字节数组)
干巴猴儿 2012-06-25
  • 打赏
  • 举报
回复
在C#里面取得的buffer1,buffer2都是乱码?要怎么样转换成正常的文字呢?
干巴猴儿 2012-06-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

在C#里面取得的buffer1,buffer2都是乱码?要怎么样转换成正常的文字呢?

结构体
C# code
[StructLayout(LayoutKind.Sequential)]
private struct PARAMS
{
uint PID;
int hKey;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
byte[] buffer1;
int cbBuffe……
[/Quote]
Trent1985 2012-06-25
  • 打赏
  • 举报
回复
http://wenku.baidu.com/view/5126f84b2b160b4e767fcf85.html?st=1看看这个,也许会有所帮助!!!
__天涯寻梦 2012-06-25
  • 打赏
  • 举报
回复
结构体
[StructLayout(LayoutKind.Sequential)]
private struct PARAMS
{
uint PID;
int hKey;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
byte[] buffer1;
int cbBuffer1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
char[] buffer2;
int cbBuffer2;
uint type;
int result;
}

C++ 和 C# 两个函数之间有什么关系?

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧