Nie mam pojęcia, na czym polega problem.PInvokeStackImbalance nie powodowane przez CallingConvention
Mam mnóstwo połączeń p/invoke, które działają bez incydentów ... z wyjątkiem tego.
Udało mi się ograniczyć mój problem do następującego kodu przykładowego.
Jeśli usunę element struct (zarówno double, jak i int), działa poprawnie.
Zakładam, że problem jest w jakiś sposób związany z układem struktury - ale kiedy robię sizeof() w C i Marshal.SizeOf() w C#, oba zwracają tę samą wartość ... tak jeśli rozmiar struktury jest taki sam w C# i C, jaki może być problem?
Najwyraźniej brakuje mi czegoś podstawowego.
SampleDLLCode.c
#pragma pack(1)
typedef struct SampleStruct {
double structValueOne;
int structValueTwo;
} SampleStruct;
__declspec(dllexport) SampleStruct __cdecl SampleMethod(void);
SampleStruct SampleMethod(void) {
return (SampleStruct) { 1, 2 };
}
Budowanie Script
gcc -std=c99 -pedantic -O0 -c -o SampleDLLCode.o SampleDLLCode.c
gcc -shared --out-implib -o SampleDLL.dll SampleDLLCode.o
C# Code
using System;
using System.Runtime.InteropServices;
namespace SampleApplication
{
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SampleStruct {
public double structValueOne;
public int structValueTwo;
}
class Program
{
[DllImport("SampleDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern SampleStruct SampleMethod();
static void Main(string[] args)
{
SampleStruct sample = SampleMethod();
}
}
}
Nic nie wyskakuje ... do cholery, spróbuj zamiana kolejności pól w struct? (obie strony, naturalnie) – JerKimball
@JerKimball Dzięki za spojrzenie. Zamiana kolejności pól w strukturze nie ma żadnego efektu. Nadal otrzymuję ostrzeżenie MDA PInvokeStackImbalance. – Steve
Czy to może być problem między GCC a .NET i podwójnym typem? Zwrócenie struct z cdecl może prowadzić do problemów zależnych od kompilatora. Sprawdź to http://stackoverflow.com/questions/13786192/methods-type-signature-is-not-pinvoke-compatible-while-calling-dll-method –