C# 能否实现从C++的dll中LoadLibrary,调用其中的API返回Form显示

zmy0611 2011-06-17 04:49:49
一个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);
}

哪位高手能修改实现这个功能?
...全文
1211 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
zmy0611 2011-06-21
  • 打赏
  • 举报
回复
终于找到解决方案了:
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)了
isjoe 2011-06-20
  • 打赏
  • 举报
回复

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函数

itwarcraft 2011-06-20
  • 打赏
  • 举报
回复
帮顶围观,最近学习实现stock.dll接口,一直没什么好的办法。。。
zmy0611 2011-06-20
  • 打赏
  • 举报
回复
高手们进来呀,再顶
三岁、就很帅 2011-06-20
  • 打赏
  • 举报
回复
围观下
zmy0611 2011-06-20
  • 打赏
  • 举报
回复
我在API中只要调用 TForm1 *f = new TForm1(NULL);
在C#中调试就会抛:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
zmy0611 2011-06-20
  • 打赏
  • 举报
回复
帮帮忙撒,急用
zmy0611 2011-06-20
  • 打赏
  • 举报
回复
谁能帮忙给个source啊,我不会写
zmy0611 2011-06-20
  • 打赏
  • 举报
回复
错的地方应该是在:
USEFORM("Unit3.cpp", Form1)
是不是dll需要特殊处理?
zmy0611 2011-06-20
  • 打赏
  • 举报
回复
isjoe:
======================================
你给的代码就是我的呀,我要的功能是:
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
遥哥_GB_Fore 2011-06-17
  • 打赏
  • 举报
回复
当然可以,你看一下c#如何调用windowsIP.如何调用。
636f6c696e 2011-06-17
  • 打赏
  • 举报
回复
hwnd = new WindowInteropHelper(this).Handle;.

110,529

社区成员

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

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

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