更改 c/c++ dll 中的参数
Changing parameters in c/c++ dll
我有一个用C语言编写的DLL。我在这个dll中有一个函数,例如:
unsigned char DLL_EXPORT getTRK(char *XML, unsigned long *Len)
{
MessageBox(NULL, XML, "Dll message", MB_OK);
char s[] = "Some string";
XML = s;
return rand()%2;
}
我需要更改 dll 中的 XML 变量值,并将此值带到我的 C# 程序中。我有关于 C# 的下一个代码:
[DllImport("Some_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte getTRK(string XML, uint Len);
...
string xml = "123";
uint len = 0;
tbXml.Clear();
if (getTRK(xml, len) == 0)
{
tbXml.AppendText(xml);
}
else
{
tbXml.AppendText("Some error!");
}
我已经尝试了不同的方法来做到这一点,但没有像需要的那样工作。我想输入 xml 变量 = "某个字符串" 的 c# prog 值。我怎样才能得到它?如果我使用 ref 或像这样:
[DllImport("Some_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte getTRK(ref string XML, ref uint Len);
...
string xml = "123";
uint len = 0;
tbXml.Clear();
if (getTRK(ref xml, ref len) == 0)
{
tbXml.AppendText(xml);
}
else
{
tbXml.AppendText("Some error!");
}
DLL 获取一些垃圾值,而不是"123"。 如果我这样做:
*XML = *s;
也什么也没发生。
C# 使用 2 字节字符串并相应地封送它们。 char* 用于存储 1 字节字符串。您必须在 DllImport 属性和 usec wchar_t* 字符串中指定字符集。
如果你需要将字符串存储在 char* 中,你可以编写一个自定义编组器,它被称为这样的东西
void ErrorWriter([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string errorMessage, string taskId, ProcessType processType);
并像这样实现
internal class Utf8Marshaler : ICustomMarshaler
{
private static Utf8Marshaler _staticInstance;
public IntPtr MarshalManagedToNative(object managedObj)
{
if (managedObj == null)
return IntPtr.Zero;
if (!(managedObj is string))
throw new MarshalDirectiveException(
"UTF8Marshaler must be used on a string.");
// not null terminated
byte[] strbuf = Encoding.UTF8.GetBytes((string) managedObj);
IntPtr buffer = Marshal.AllocHGlobal(strbuf.Length+1);
Marshal.Copy(strbuf, 0, buffer, strbuf.Length);
// write the terminating null
Marshal.WriteByte(buffer + strbuf.Length, 0);
return buffer;
}
public object MarshalNativeToManaged(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero)
return string.Empty;
int length = 1;
IntPtr offsetPtr = IntPtr.Add(pNativeData, 1);
while (Marshal.ReadByte(offsetPtr) != 0)
{
offsetPtr = IntPtr.Add(offsetPtr, 1);
length++;
}
byte[] strbuf = new byte[length];
Marshal.Copy(pNativeData, strbuf, 0, length);
string data = Encoding.UTF8.GetString(strbuf);
return data;
}
public void CleanUpNativeData(IntPtr pNativeData)
{
Marshal.FreeHGlobal(pNativeData);
}
public void CleanUpManagedData(object managedObj)
{
}
public int GetNativeDataSize()
{
return -1;
}
public static ICustomMarshaler GetInstance(string cookie)
{
if (_staticInstance == null)
{
return _staticInstance = new Utf8Marshaler();
}
return _staticInstance;
}
}
相关文章:
- 从C++dll访问C#中的一行主要参数
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 如何在窗口中使用注入的 dll 中的参数调用函数
- WinRT 应用调用 win32 c++ dll 发送参数
- PowerShell 使用结构类型参数调用 C++ DLL 的导出函数
- 将 std::string 作为参数从一个 DLL 传递到另一个 DLL 引发访问冲突错误
- 使用参数调用远程进程中的函数(注入的 DLL)
- 如何使用指针作为参数在 C# 中包装C++ DLL?
- 从 C# GUI 将 char * 参数传递给C++ dll 函数
- 使用 c++ 调用.dll的默认参数的函数
- 使用参数的 C# 委托回调会导致从 DLL 调用时C++访问冲突
- 使用安全模式从DLL(通过(INTPTR)参数传递到该函数)获取char **
- Java:加载带有char **的C DLL,将回调作为参数
- 从C++调用 Delphi DLL IStream 参数的问题
- clr 如何使用本机 c++ dll 的引用'&'参数调用函数?
- 如果在调用 DLL 中的函数时没有传递足够的参数,会发生什么情况?
- 如何在 C# 中设置或获取 DLL 库的参数?
- 当DLL( 标头)是预期的交付时,如何在C 中实现预测模型(具有100个参数的10种类型)
- 当参数之一是指针数组时,如何从C#调用C DLL
- 从未知dll(c++)中检索函数(名称、返回类型、参数)