Non ho idea di quale sia il problema.PInvokeStackImbalance non causato da CallingConvention
Ho un sacco di p/invocare chiamate che funzionano senza inconvenienti ... tranne questo.
Sono riuscito a ridurre il mio problema al seguente codice di esempio.
Se rimuovo uno dei membri della struct (sia il doppio che l'int), funziona correttamente.
Sto assumendo che il problema sia in qualche modo correlato al layout della struct - ma quando faccio una sizeof() in C e uno Marshal.SizeOf() in C#, entrambi restituiscono lo stesso valore ... quindi se la dimensione della struct è la stessa in C# e C, quale potrebbe essere il problema?
Mi manca ovviamente qualcosa di semplice qui.
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 };
}
costruire Script
gcc -std=c99 -pedantic -O0 -c -o SampleDLLCode.o SampleDLLCode.c
gcc -shared --out-implib -o SampleDLL.dll SampleDLLCode.o
C# Codice
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();
}
}
}
Niente salti fuori ... per il gusto di farlo, provare a scambiare l'ordine dei campi nella struct? (entrambi i lati, naturalmente) – JerKimball
@JerKimball Grazie per la ricerca. Scambiare l'ordine dei campi nella struttura non ha alcun effetto. Ricevo ancora l'avviso MDA PInvokeStackImbalance. – Steve
Potrebbe trattarsi di un problema tra GCC vs .NET e il doppio? Restituire una struttura con cdecl può portare a problemi dipendenti dal compilatore. Controlla questo http://stackoverflow.com/questions/13786192/methods-type-signature-is-not-pinvoke-compatible-while-calling-dll-method –