Having the following code in C++:
- nConId is Connection Identifier
- pParName the parameter name
- pSubName the subParameter Name (if any)
- pValue_out a pointer to a char array of lenght FCL_PAR_VALUE_LENGH
- nValueSize the real size of pValue_out vector (at least FCL_PAR_VALUE_LENGH)
extern "C" MY_API int ReadParameter(const ConnectionId_T nConId, const char* pParName,
const char *pSubName, char *pValue_out, const int nValueSize );
My try is:
[DllImport("mydll.dll", CharSet = CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
public static extern int ReadParameter(ConnectionId_T pConId, IntPtr pParName,
ref IntPtr pSubName, ref IntPtr[] pValue_out, int nValueSize);
I'm using the following code to call that function:
# nConId is returned from another function and the his value is 0
public const int FCL_PAR_VALUE_LENGH = 128;
string param_string = "AUXF";
IntPtr pParName = (IntPtr)Marshal.StringToHGlobalAnsi(param_string);
string subparam_string = "T";
IntPtr pSubName = (IntPtr)Marshal.StringToHGlobalAnsi(subparam_string);
IntPtr[] aParValue = new IntPtr[FCL_PAR_VALUE_LENGH];
int returnedValue = ReadParameter(nConId, pParName, ref pSubName,
ref aParValue, FCL_PAR_VALUE_LENGH);
When I run the code I get an AccessViolationException, so I guess there's something wrong in my call.
Do I've my marshall wrong? What do I've to change in the code in order to get the good reponse?
PS: I also know that the call returns also something to aParValue
.
You're working too hard with those char*
s. It's perfectly legal (and encouraged) to marshal a System.String
for input, and a StringBuilder
for output.
[DllImport("mydll.dll", CharSet = CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)]
public static extern int ReadParameter(
ConnectionId_T pConId,
string pParName,
string pSubName,
StringBuilder pValue_out,
int nValueSize);
usage
const int sbLength = 256; //use a domain relevant value
StringBuilder sb = new StringBuilder(sbLength + 1); //for null character, hard to say if you need it without seeing the C++ code, but easier to just add it than find out.
int result = ReadParameter(conId, "paramname", "paramsubname", sb, sbLength);
You haven't given any indication about the underlying type of ConnectionId_T
so I'm assuming you've ruled that out as an issue.