2010-04-26 8 views
1

J'ai la DLL simple suivante dans le code non géré C++;C# Wrapper au code C++ natif, envelopper un paramètre qui est un pointeur vers un tableau

extern "C" __declspec(dllexport) void ArrayMultiplier(float (*pointerArray)[3], int scalar, int length); 

void ArrayMultiplier(float (*pointerArray)[3], int scalar, int length) 
{ 
    for (int i = 0 ; i < length ; length++) 
    { 
     for (int j = 0; j < 3; j++) 
     { 
      pointerArray[i][j] = pointerArray[i][j] * scalar; 
     } 
    } 
} 

J'ai essayé d'écrire la fonction enveloppe suivante pour ce qui précède en C#:

[DllImport("sample.dll")] 
public static extern void ArrayMultiplier(ref float elements, int scalar, int length); 

où les éléments est un tableau 3x3 dimentionnelle 2:

public float[][] elements = 
     { 
      new float[] {2,5,3}, 
      new float [] {4,8,6}, 
      new float [] {5,28,3} 
     }; 

Le code ci-dessus compiles, mais le programme se bloque lorsque la fonction wrapper est appelée:

Wrapper.ArrayMultiplier(ref elements, scalar, length); 

S'il vous plaît aidez-moi, et dites-moi ce qui est mal avec le code ci-dessus, ou comment un emballage peut être écrit pour un simple C++ fonction:

void SimpleFunction(float (*pointerToArray)[3]); 

Merci à tous à l'avance

+1

Une raison pour laquelle vous n'avez PAS ACCEPTÉ cette réponse? Ça me va bien! – Goz

Répondre

1

Il y a quelques façons de le faire.

La route dangereuse, qui fonctionne bien avec des tableaux 2D (que vous avez):

[DllImport("fastprocessing.dll", EntryPoint = "MyFunc")] 
    public static extern void MyFuncViaDLL(int inPtr, int outPtr, int inSize1, int size2, int param); 

appelé via

private unsafe float[] MyFunc(float[] inData, int inSize1, int inSize2, int param1, int param2) { 
     float[] theOutData = new float[inChannelData.Length]; 
     fixed (float* inBufferPtr = &inChannelData[0]) { 
      fixed (float* outBufferPtr = &theOutData[0]) { 
       MyFuncViaDLL((int)inBufferPtr, (int)outBufferPtr, inSize1, inSize2, param); 
      } 
     } 
     return theOutData; 
    } 

qui fonctionnera de façon non sécuritaire, mais vous auriez besoin de changez vos tableaux d'entrée en tableaux 1D. Je pense que c'est une meilleure idée de toute façon, mais c'est comme ça que je pense.

Si vous voulez être sûr à ce sujet, ajoutez un autre paramètre qui est la taille du tableau lui-même, puis faites un peu de marshaling. Encore une fois, cependant, vous aurez besoin d'entrer dans les tableaux 1D:

, vous voulez au lieu de faire un peu de triage, comme suit:

[DllImport("fastprocessing.dll", EntryPoint = "MyFunc")] 
    public static extern void MyFuncViaDLL([MarshalAs(UnmanagedType.LPArray)]float[] inPtr, int size1, int size2, int totalSize, int param2); 

Ensuite, il suffit d'appeler la fonction directement:

MyFuncViaDLL(array, size1, size2, size1*size2, param1, param2); 

C++ changerait alors à:

void ArrayMultiplier(float *pointerArray, int inSize1, int inSize2, int inTotalSize, int scalar) 
{ 
    int i, j, index; 
    for (i = 0 ; i < size1; i++)//note that length++ would be very very wrong here 
    { 
     for (j = 0; j < size2; j++) 
     { 
      index = i*size2 + j; 
      if(index >= inTotalSize) { return; } //avoid walking off the end 
      pointerArray[i*size2 + j] *= scalar; 
     } 
    } 
} 

Si vous voulez, vous pouvez ajouter à la vérification contre lengt totale h pour vous assurer que vous ne partez pas de la fin, mais ce sera un assez gros succès (assez pour ne pas utiliser C++), comme si les instructions ne sont pas libres. Après avoir fait tous les de cela, cependant, je dois demander - pourquoi ne pas le faire directement en C#, et vous épargner les tracas des services interop comme le marshalling? C++ a tendance à être plus rapide pour les choses compliquées, mais pour une promenade rapide, j'ai vu C# se comporter plutôt bien. Il peut être assez rapide en C#, une fois qu'il s'agit d'un tableau 1D:

int i; 
for (i = 0; i < array.length; i++){ 
    array[i] *= scalar; 
} 
+0

Ce fut une aide précieuse, je vous remercie – user326075

Questions connexes