2011-09-03 67 views
0

我使用下面的DllImport:参数从C#代码错误地传递到C++ DLL

[DllImport(@"someDLL.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern UINT64 someFunc(int arga, int argb, int argc); 

我打电话的功能如下:

someFunc(0,0,1); 

H中的文件I声明函数:

extern "C" __declspec(dllexport) UINT64 someFunc(int arga, int argb, int argc); 

CPP:

UINT64 someFunc(int arga, int argb, int argc) 
{ 
    ... 
} 

在C++代码中,我收到奇怪的值(例如1218628,20140292,1219020)。

任何想法为什么?

+1

您可以看到C#代码和C++代码,但无法解决这个问题。您希望我们只能从C#代码中完成它是不公平的。你在interop上标记了它,这意味着互操作有两个方面。你为什么拒绝我们进入其中一方? –

+1

添加的代码c –

+1

这是一个会员函馆?如果没有,那么我可以看到没有错。 C++肯定使用cdecl吗? –

回答

0

您没有显示C++代码,所以我没有在代码中看到问题。所以,我尝试自己重新创建它。我创建了一个调用DLL的C#WPF项目。

C#:

 
     [DllImport(@"c:\users\owner\documents\visual studio 2010\Projects\MyDll\Release\MyDll.dll", 
      CallingConvention = CallingConvention.Cdecl)] 
     private static extern UInt64 someFunc(int arga, int argb, int argc); 

     private void DoIt_Click(object sender, RoutedEventArgs e) 
     { 
      UInt64 val = someFunc(0, 0, 1); 
      ResultLabel.Content = val.ToString(); 
     } 

C++ DLL:

 
extern "C" __declspec(dllexport) unsigned __int64 someFunc(int arga, int argb, int argc) 
{ 
    CString s; 
    s.Format(L"%d\t%d\t%d", arga, argb, argc); 
    AfxMessageBox(s); 
    return arga + argb + argc; 
} 

从C++消息框显示0 0 1如预期和C#代码获取1返回正常。

+0

如果有问题,我从dumpbin/exports中获取EntryPoint文本MyDLL.dll – jschroedl

+0

使用extern“C”来避免修改,就像问题 –

+0

中的代码一样,这也适用于我。还调整了我的代码以使用未签名的__int64。所以看起来我们看不到问题。 – jschroedl

0

如果可以,使用__stdcall而不是__cdecl,在__stdcall中是执行堆栈清理的C DLL,并且是使用Windows C dll的标准方式。

在C代码中指定调用约定也是一种很好的行为,为了可读性和C++项目设置都可以指定缺省情况下使用的调用约定。

尝试明确地设置__cdecl,也许C++编译器使用__stdcall编译它。

extern "C" __declspec(dllexport) UINT64 __cdecl someFunc(int arga, int argb, int argc); 
+1

只要你在两边使用相同的东西,你使用哪一个并不重要。 –