C # Marshalling double * à partir de C ++ DLL?
J'ai une DLL C++ avec une fonction exportée:
extern "C" __declspec(dllexport) double* fft(double* dataReal, double* dataImag)
{
[...]
}
La fonction calcule la FFT de les deux tableaux (réel et imaginaire) renvoie un double tableau avec le réel de l'imaginaire composants entrelacé: { Re, Mi, Ré, Mi, ... }
Je ne sais pas comment appeler cette fonction en C#.
Ce que je fais est:
[DllImport("fft.dll")]
static extern double[] fft(double[] dataReal, double[] dataImag);
et quand je l'ai tester comme ceci:
double[] foo = fft(new double[] { 1, 2, 3, 4 }, new double[] { 0, 0, 0, 0 });
- Je obtenir un MarshalDirectiveException exception:
Ne peut maréchal de "valeur de retour": les Invalides réussi/non géré type de combinaison.
Je suppose que c'est parce que le C++ double*
n'est pas tout à fait la même qu'en C# double[]
mais je ne suis pas sûr de la façon de le résoudre. Des idées?
Edit:
J'ai changé les signatures pour que je soit maintenant pass certaines informations supplémentaires:
extern "C" __declspec(dllexport) void fft(double* dataReal, double* dataImag, int length, double* output);
Nous savons toujours la longueur de output
sera 2x length
et
[DllImport("fft.dll")]
static extern void fft(double[] dataReal, double[] dataImag, int length, out double[] output);
testé comme ceci:
double[] foo = new double[8];
fft(new double[] { 1, 2, 3, 4 }, new double[] { 0, 0, 0, 0 }, 4, out foo);
Maintenant, je suis pas un AccessViolationException plutôt qu'un MarshalDirectiveException.
source d'informationauteur Ozzah
Vous devez vous connecter pour publier un commentaire.
Il y a quelques problèmes avec votre exemple:
Au lieu de cela, ma suggestion serait de définir la fft cette façon:
Le correspondant de P/Invoke signature:
Et puis un exemple d'appel:
Edit: la mise à jour basé sur ce que la fft est décrit à faire.
Il n'est pas nécessaire de modifier la signature.
Vous pouvez utiliser la suite:
Alors vous aurez besoin de copier des octets retournés
IntPtr
. Puisque vous connaissez la taille de la sortie est le double de l'entrée, vous le faites de manière suivante:La
result
contiendra octets retournés par lefft
fonction.EDIT:
Je crois que vous trouverez
P/Invoke Interop Assistant
outil utile: Géré en Natif, et COM InteropCe n'est pas bon prototype pour l'interopérabilité. Vous pouvez deux façons de résoudre ce problème:
Le retour de la mémoire de référence serait de travailler correctement que dans le cas où le mémoire a été allouée avec CoTaskMemAlloc fonction. Othrwise vous prendra exception d'exécution au cours de libérer de la mémoire (le CLR toujours essayer de libérer de l'returnning mémoire avec CoTaskMemFree).
Je pense que le mieux serait de la première manière, il décrit en Pierre Huene de réponse.