I am making a DLL wrapper for some C++ code and have run into an issue. It will be easier for me to illustrate my problem after providing some sample code.
In my C++ application's .h file:
#pragma once
namespace Wrapper {
extern __declspec(dllexport)
void SANDBOX(int arrayLength, int* intArray);
}
In my C++ application's .cpp file:
#include "stdafx.h"
#include "Wrapper.h"
#include <windows.h>
using namespace Wrapper;
extern "C"{
BOOL APIENTRY DllMain(
HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
return TRUE;
}
__declspec(dllexport) void SANDBOX(int* arrayLength, int* intArray[])
{
if(*intArray == NULL)
{
*arrayLength = 5;
return;
}
else
{
int i = 0;
for(i = 0; i < (*arrayLength); i++)
{
(*intArray)[i] = 1 + i*i;
}
}
}
}
My C# application imports the method like so:
const string dllFileLocation = "Wrapper.dll";
[DllImport(dllFileLocation, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public extern static void SANDBOX(ref int arrayLength, ref int[] intArray);
And finally, my C# application calls the code in a form like this:
//Initialize some things
string outString;
int numInArray = -1;
int[] iArray = null;
//Fill the numInArray integer
Wrapper_Handle.SANDBOX(ref numInArray, ref iArray);
//Lets initialize the array and print the values
iArray = new int[numInArray];
outString = "";
foreach(int i in iArray)
{
outString += i + "\n";
}
MessageBox.Show(outString);
//Now lets put values into the array and print the new ones out
Wrapper_Handle.SANDBOX(ref numInArray, ref iArray);
outString = "";
foreach(int i in iArray)
{
outString += i + "\n";
}
MessageBox.Show(outString);
So, what I would expect to happen is I make a null array to get the number of values to initialize. So I get 5 out, make a new array, and print it. It get what I would expect: a message box with 0 five times. However, after the method is called again the second message box is simply the number 1, with no other values. It would appear that the other 4 values are "cut" off of the array, and the C# application cannot see them anymore.
I have successfully imported many other functions from the C++ .DLL. Its this array notation which is causing issues. When debugging the .DLL, the values are properly passed to the C++ code, and they are assigned.
Does anyone know why the C# application "loses" the other 4 values? It does not matter the length of the array, only the first value is ever kept after the call to the method.
Thanks in advance. Any help is greatly appreciated.
EDIT-- The solution to my problem was provided in a comment to this question. I am posting my changes below:
C++ .h file:
#pragma once
namespace Wrapper {
extern __declspec(dllexport)
void SANDBOX(int arrayLength, int* intArray);
}
C++ .cpp file:
#include "stdafx.h"
#include "Wrapper.h"
#include <windows.h>
using namespace Wrapper;
extern "C"{
BOOL APIENTRY DllMain(
HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
return TRUE;
}
__declspec(dllexport) void SANDBOX(int* arrayLength, int* intArray)
{
if(intArray == NULL)
{
*arrayLength = 5;
return;
}
else
{
int i = 0;
for(i = 0; i < (*arrayLength); i++)
{
(intArray)[i] = 1 + i*i;
}
}
}
}
C# import:
const string dllFileLocation = "Wrapper.dll";
[DllImport(dllFileLocation, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public extern static void SANDBOX(ref int arrayLength, int[] intArray);
C# calls:
string outString;
int numInArray = -1;
int[] iArray = null;
Wrapper_Handle.SANDBOX(ref numInArray, iArray);
iArray = new int[numInArray];
outString = "";
foreach(int i in iArray)
{
outString += i + "\n";
}
MessageBox.Show(outString);
Wrapper_Handle.SANDBOX(ref numInArray, iArray);
outString = "";
foreach(int i in iArray)
{
outString += i + "\n";
}
MessageBox.Show(outString);