Interaction with C / C ++ procedure in C # causes rip

I have a provider API that I want to use in my C # Windows Forms application . The problem is that no matter what P / Invoke I try, I get a failure on the line, stating that the call is unbalanced on the stack. I tried to work with the seller, but they do not have Visual Studio 2012, and I have no experience with C # or .NET and after several back and forth emails, they basically washed their problems.

Here is their official C / C ++ declaration

const char *<dll name here>(int Param1, const char *Param2, const char *Param3, unsigned long Param4, unsigned short Param5, unsigned short Param6, unsigned short Param7, unsigned short Param8, unsigned short Param9); 

Here is the recent P / Invoke DLLImport line I tried.

 [System.Runtime.InteropServices.DllImport( "<dll name here>", EntryPoint = "<AnsiFunctionName>", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)] public static extern String <AnsiFunctionName>(int Param1, String Param2, String Param3, ulong Param4, Int16 Param5, Int16 Param6, Int16 Param7, Int16 Param8, Int16 Param9); 

Here is the actual error message:

Subject: PInvokeStackImbalance detected

P / Invoke '' function call is unbalanced on the stack. This is likely due to the fact that the PInvoke managed signature does not match the unmanaged target signature. Verify that the calling agreement and P / Invoke signature settings match the target unmanaged signature.

I tried different things, even setting the type of void return. I did not try to use the return type. I tried instead of Strings, StringBuilders and IntPtrs. No matter what I tried, nothing works.

I mentioned the seller after reading the article here about Stack Overflow returning a string is dangerous and should never be done. Their answer was:

"The line-return issues mentioned on this page are not related to our functions. They return a pointer to a statically allocated line, so you don’t need to free it (and do not try to do this). It seems that" UnmanagedType.LPStr "should work ( although IntPtr should also work with proper conversions or casting).

Update # 1: As mentioned in the comment, I used uint, not ulong, up to this post. I just thought the comparison is better. Uint and ulong do not work.

Update # 2: Maybe providing the actual function name will help. This is Armadillo CreateCodeShort3A. Going forward, I use pure .NET, but I still need to interact with this, it's just not possible at the moment. Moreover, the problem made me curious as to why I cannot solve something that is as simple as P / Invoke. After all, how many options are there? (not a serious question).

+4
source share
1 answer

Here are the features that I see:

  • The return value must not be a String . Use IntPtr and convert to string using Marshal.PtrToStringAnsi .
  • C ++ type unsigned long must be mapped to uint . You used ulong in C #, which is a 64-bit type. In C ++ on Windows, an unsigned long is a 32-bit unsigned long type.
  • C ++ type unsigned short must be mapped to ushort .
  • The calling convention used by the C ++ DLL is possibly cdecl . Add CallingConvention = CallingConvention.Cdecl to P / Invoke .
  • Do not use SetLastError for such a function. This is used with Win32 API functions that return error conditions through GetLastError . This dll file almost certainly does not work.

So P / Invoke should look something like this:

 [DllImport(@"mydll.dll", CallingConvention=CallingConvention.Cdecl)] public static extern IntPtr FunctionName( int Param1, string Param2, string Param3, uint Param4, ushort Param5, ushort Param6, ushort Param7, ushort Param8, ushort Param9 ); 
+2
source

Source: https://habr.com/ru/post/1443252/


All Articles