如何使用WCHAR * out参数从C#调用C函数?

我在编组方面遇到了一些问题,我自己也搞不清楚了。 我已经搜索了这个主题,但还没有运气,所以基本上我试图从我的托管C#应用程序调用非托管C函数。 C函数的签名如下所示:

long MyFunction(WCHAR* upn, long upnSize, WCHAR* guid, long* guidSize); 

我没有访问.dll文件,我只知道该函数正在暴露使用,我知道函数应该做什么,但我不知道里面发生了什么,所以函数收到一个WCHAR * upn持有UserPricipalName和长度与提供的UPN的长度。 还传递WCHAR指针,其中该函数写回与传递的UPN相关联的相应GUID。 guidSize指针提供指针的大小,如果它太小,则写入的GUID未完全写入。 如果一切顺利,函数应返回0(当从c#调用时,它从未发生过)

现在我调用和调用此函数的努力如下所示:

 [DllImport(@"MyDll.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public static extern long MyFunction(IntPtr upnPtr, long upnSize, [Out, MarshalAsAttribute(UnmanagedType.LPWStr) ] StringBuilder guidPtr, IntPtr guidSizePtr); //my attempt to call the Dll's exposed function string upn = foo@bar.com; long upnSize = upn.Length; IntPtr upnPtr = Marshal.StringToHGlobalUni(upn); IntPtr guidSizePtr = Marshal.AllocHGlobal(sizeof(long)); Marshal.WriteInt32(GuidSizePtr, 128); var guidSB = new StringBuilder(128); result = MyFunction(upnPtr, upnSize, guidSB, guidSizePtr); 

结果我收到一个AccessViolationException。 我玩了很多变种来调用这个函数,但是我从来没有设法接收到0作为返回值而且我从来没有能够像我应该那样读出GUID。

任何帮助都将不胜感激。

将函数声明为:

  [DllImport(@"MyDll.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] public static extern int MyFunction([MarshalAsAttribute(UnmanagedType.LPWStr)] string upnPtr, int upnSize, [MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder guidPtr, ref int guidSizePtr); 

称其如下:

  string upn = "foo@bar.com"; var guidSB = new StringBuilder(128); int guidSizePtr =guidSB.Capacity; MyFunction(upn, upn.Length, guidSB, ref guidSizePtr); 

请注意,C ++中的长度为32位,因此您应该在C#代码中将所有此类实例定义为int。