一个C++的窗体Form,编译在dll中。dll中开放一个API供C#调用C#能否LoadLibrary这个dll,调用其中的API,在该API中,创建窗体并返回其句柄,然后在C#中显示?
大概的代码这样的:
C++:
extern "C" __declspec(dllexport) WINAPI int TestMethod()
{
//创建Form1
return (int)(Form1->Handle); //返回Form的句柄,这里有问题
}
C#:DllInvoke.cs
[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(string path);
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
private IntPtr hLib;
public DllInvoke(String DLLPath)
{
hLib = LoadLibrary(DLLPath);
}
~DllInvoke()
{
FreeLibrary(hLib);
}
//将要执行的函数转换为委托
public Delegate Invoke (string APIName,Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
}
public delegate IntPtr TestDelegate();
Form1.cs:
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);
public void ShowCForm()
{
DllInvoke di = new DllInvoke("dll全路径名");
TestDelegate td = di.Invoke("TestMethod", typeof(TestDelegate));
IntPtr handle = td(); //
SetParent(handle, this.Handle); // Remove border and whatnot
SetWindowLong(handle, GWL_STYLE, WS_VISIBLE); // Move the window to overlay it on this window
MoveWindow(handle, 0, 0, this.Width, this.Height, true);
}哪位高手能修改实现这个功能?
大概的代码这样的:
C++:
extern "C" __declspec(dllexport) WINAPI int TestMethod()
{
//创建Form1
return (int)(Form1->Handle); //返回Form的句柄,这里有问题
}
C#:DllInvoke.cs
[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(string path);
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
private IntPtr hLib;
public DllInvoke(String DLLPath)
{
hLib = LoadLibrary(DLLPath);
}
~DllInvoke()
{
FreeLibrary(hLib);
}
//将要执行的函数转换为委托
public Delegate Invoke (string APIName,Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
}
public delegate IntPtr TestDelegate();
Form1.cs:
[DllImport("user32.dll", SetLastError = true)]
private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("user32.dll", EntryPoint = "SetWindowLongA", SetLastError = true)]
private static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);
public void ShowCForm()
{
DllInvoke di = new DllInvoke("dll全路径名");
TestDelegate td = di.Invoke("TestMethod", typeof(TestDelegate));
IntPtr handle = td(); //
SetParent(handle, this.Handle); // Remove border and whatnot
SetWindowLong(handle, GWL_STYLE, WS_VISIBLE); // Move the window to overlay it on this window
MoveWindow(handle, 0, 0, this.Width, this.Height, true);
}哪位高手能修改实现这个功能?
解决方案 »
- 高分急求,谢谢
- 在VS2005中定义了一个用户控件的逻辑CS类以后,是不是要编译以后才能使用的?
- 新手问个写字符串到文本的问题。
- 请教高人,如何能实现从word进程中获取它的application对象
- -----------急啊急,高手,关于DateGrid的一个问题?-----------------------
- Convert.ToDateTime的问题,在线等
- 急求水晶报表10如何发布到客户端----高分求解
- 怎么在picturebox里面移动画的点
- 如何得到用户屏幕分辨率的大小?
- 要求输入用户名和密码才能进入系统的登录对话框怎么实现阿??
- 数据库文档生成器 关于SqlCE数据库表结构的导出
- USB 小票打印机直接打印问题
在C#中调试就会抛:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
public class DllInvoke
{
[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(String path);
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
private IntPtr hLib;
public DllInvoke(String DLLPath)
{
hLib = LoadLibrary(DLLPath);
}
~DllInvoke()
{
FreeLibrary(hLib);
}
//将要执行的函数转换为委托
public Delegate Invoke(String APIName,Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api,t);
}
}
下面代码进行调用
public delegate int Compile(String command, StringBuilder inf);//编译
DllInvoke dll = new DllInvoke(Server.MapPath(@"~/Bin/Judge.dll"));
Compile compile = (Compile)dll.Invoke("Compile", typeof(Compile));
StringBuilder inf;
compile(@“gcc a.c -o a.exe“,inf); //这里就是调用我的DLL里定义的Compile函数
======================================
你给的代码就是我的呀,我要的功能是:
dll中的一个API能返回Form的Handle1,在C#中
SetParent(Handle1, this.Handle);
SetWindowLong(Handle1, GWL_STYLE, WS_VISIBLE);
MoveWindow(Handle1, 0, 0, this.Width, this.Height, true);
将该Handle1指向的Form嵌入到C#的Form上显示。
现在的的问题是:
在API中
extern "C" __declspec(dllexport) WINAPI int TestMethod()
{
//return 0;//直接return,能正确调用
TForm1 *f = new TForm1(); //这句报:尝试读取或写入受保护的内存。这通常指示其他内存已损坏
return (int)(f->Handle); //可以直接返回Handle吗?? -> C#.Handle1
}
以及如何返回该Handle
USEFORM("Unit3.cpp", Form1)
是不是dll需要特殊处理?
API中:
HMODULE Inst = LoadLibrary("TestCall.dll");
if (Inst)
{
TestCall = (int(__fastcall*) (int InParam))GetProcAddress(Inst, "@TestCall");
if (TestCall)
return TestCall(a); //得到Form的Handle
}
return 0;
这样就不用 USEFORM("Unit3.cpp", Form1)了