使用多个指针在 C# 中编组本机 .dll
Marshalling native .dll in C# with multiple pointers
在 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 );
我的尝试是:
[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);
我正在使用以下代码调用该函数:
# 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);
当我 运行 代码时,我得到一个 AccessViolationException,所以我猜我的调用有问题。
我的编组有误吗?为了获得良好的响应,我必须更改代码中的哪些内容?
PS: 我也知道调用returns也有事要aParValue
.
你为那些 char*
工作太辛苦了。编组输入 System.String
和输出 StringBuilder
是完全合法的(并且受到鼓励)。
[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);
用法
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);
您没有给出任何关于 ConnectionId_T
的基础类型的指示,因此我假设您已将其排除在外。
在 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 );
我的尝试是:
[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);
我正在使用以下代码调用该函数:
# 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);
当我 运行 代码时,我得到一个 AccessViolationException,所以我猜我的调用有问题。
我的编组有误吗?为了获得良好的响应,我必须更改代码中的哪些内容?
PS: 我也知道调用returns也有事要aParValue
.
你为那些 char*
工作太辛苦了。编组输入 System.String
和输出 StringBuilder
是完全合法的(并且受到鼓励)。
[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);
用法
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);
您没有给出任何关于 ConnectionId_T
的基础类型的指示,因此我假设您已将其排除在外。