一个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);
        }哪位高手能修改实现这个功能?

解决方案 »

  1.   

    hwnd = new WindowInteropHelper(this).Handle;.
      

  2.   

    当然可以,你看一下c#如何调用windowsIP.如何调用。
      

  3.   

    谁能帮忙给个source啊,我不会写
      

  4.   

    我在API中只要调用 TForm1 *f = new TForm1(NULL);
    在C#中调试就会抛:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
      

  5.   


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

  6.   

    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
     
      

  7.   

    错的地方应该是在:
               USEFORM("Unit3.cpp", Form1)
    是不是dll需要特殊处理?
      

  8.   

    终于找到解决方案了:
    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)了