2013-12-19 56 views
0

我挣扎了一会儿,还是没能想出如何编写代码在C#侧C#的PInvoke与C结构包含函数指针

C++ DLL

typedef void (WINAPI *P_HelloWorld)(void); 
typedef struct { 

P_HelloWorld pHelloWorld; 

}FUNC_PARAM; 

void Func4(FUNC_PARAM* pFunc) 
{ 
    pFunc.pHelloWorld(); 
} 

C#方:

public delegate void P_HelloWord(); 
[StructLayout(LayoutKind.Sequential)] 
public struct FUNC_PARAM 
{ 
    public P_HelloWord pHelloWorld; 
} 

    [DllImport("EMV_DLL.dll")] 

    public extern static void Func4(FUNC_PARAM[] pFunc); 

void main() 
{ 
    FUNC_PARAM g; 
    g.pHelloWorld = new P_HelloWord(this.myHelloWorld); 
    Func4(new FUNC_PARAM[] { g }); 
    } 

void myHelloWorld() 
{ 
    MessageBox.Show("My Hello World"); 
} 

上面的C#代码不起作用,当执行Func4函数时,它会抛出内存异常。

有人可以帮助我吗?

+0

您的C++代码不能编译。你的C#代码有一个无效的main。请你可以发布真实的代码。请注意,'pFunc'参数不是一个数组。 –

回答

3

由于您的问题中的代码无法编译,因此您似乎没有发布真实的代码。无论如何,下面的工作。

C++

typedef void (WINAPI *P_HelloWorld)(void); 

typedef struct { 
    P_HelloWorld pHelloWorld; 
} FUNC_PARAM; 

void Func4(FUNC_PARAM* pFunc) 
{ 
    pFunc->pHelloWorld(); 
} 

C#

public delegate void P_HelloWord(); 

public struct FUNC_PARAM 
{ 
    public P_HelloWord pHelloWorld; 
} 

[DllImport(@"MyDll.dll", CallingConvention = CallingConvention.Cdecl)] 
public extern static void Func4(ref FUNC_PARAM pFunc); 

static void Main(string[] args) 
{ 
    FUNC_PARAM pFunc; 
    pFunc.pHelloWorld = myHelloWorld; 
    Func4(ref pFunc); 
    Console.ReadLine(); 
} 

static void myHelloWorld() 
{ 
    Console.WriteLine("Boo!"); 
} 

几点:

  1. Func4参数不是一个数组。这是结构的地址。这使得它在C#中成为ref
  2. Func4的调用约定为cdecl
  3. Func4的执行不会在您的代码中编译。我把它固定在我的。
  4. 您的C#主要功能不正确。它必须是根据我的代码声明的函数。

显然,你正在使用CE。那里只有一个调用约定,stdcall。至于在注释中报告的错误,停止将代表包装在结构中并直接传递它。

+0

该平台是Windows CE 5.0,.NET Compact Framework 2.0/3.5不支持CallingConvention.Cdecl。我试图用ref作为pFunc参数的关键字,但没有成功,并且它抛出“NotSupportedException” –

+0

@user你是在开玩笑吗?我可以在哪里找到这些信息?你怎么可能没有意识到它是相关的?为什么现在不在这个问题上?为什么假代码仍然存在? –

+0

我很抱歉,因为从一开始我就没有意识到Windows CE中的PInvoke与Windows不同,直到我测试你的代码。 –