C#delegate中的Marshal va_list
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#delegate中的Marshal va_list,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2233字,纯文字阅读大概需要4分钟。
内容图文
![C#delegate中的Marshal va_list](/upload/InfoBanner/zyjiaocheng/792/b7c7897910434b0ea25692a2f68e840c.jpg)
我正在努力从c#开始这项工作:
C头:
typedef void (LogFunc) (const char *format, va_list args);
bool Init(uint32 version, LogFunc *log)
C#实现:
static class NativeMethods
{
[DllImport("My.dll", SetLastError = true)]
internal static extern bool Init(uint version, LogFunc log);
[UnmanagedFunctionPointer(CallingConvention.Cdecl, SetLastError = true)]
internal delegate void LogFunc(string format, string[] args);
}
class Program
{
public static void Main(string[] args)
{
NativeMethods.Init(5, LogMessage);
Console.ReadLine();
}
private static void LogMessage(string format, string[] args)
{
Console.WriteLine("Format: {0}, args: {1}", format, DisplayArgs(args));
}
}
这里发生的是对NativeMethods.Init的调用回调LogMessage并将来自非托管代码的数据作为参数传递.这适用于大多数情况,其中参数是字符串.但是,有一个调用格式为:
版本%d的已加载插件%s.
并且args只包含一个字符串(插件名称).它们不包含版本值,这是有道理的,因为我在委托声明中使用了string [].问题是,如何编写委托来获取字符串和int?
我尝试使用object [] args并得到了这个异常:
在从非托管VARIANT到托管对象的转换过程中检测到无效的VARIANT.将无效的VARIANT传递给CLR可能会导致意外的异常,损坏或数据丢失.
编辑:
我可以将委托签名更改为:
internal delegate void LogFunc(string format, IntPtr args);
我可以解析格式并找出期望的参数和类型.例如.对于版本%d的已加载插件%s.我期待一个字符串和一个int.有没有办法从IntPtr中获取这两个?
解决方法:
以防万一它可以帮助某人,这里有一个解决问题的解决方案.代表被宣布为:
[UnmanagedFunctionPointer(CallingConvention.Cdecl, SetLastError = true)] // Cdecl is a must
internal delegate void LogFunc(string format, IntPtr argsAddress);
argsAddress是数组启动的非托管内存地址(我认为).格式给出了数组的大小.知道了这一点,我就可以创建托管阵列并填充它. Pseuso代码:
size <- get size from format
if size = 0 then return
array <- new IntPtr[size]
Marshal.Copy(argsAddress, array, 0, size);
args <- new string[size]
for i = 0 to size-1 do
placeholder <- get the i-th placeholder from format // e.g. "%s"
switch (placeholder)
case "%s": args[i] <- Marshal.PtrToStringAnsi(array[i])
case "%d": args[i] <- array[i].ToString() // i can't explain why the array contains the value, but it does
default: throw exception("todo: handle {placeholder}")
说实话,我不确定这是怎么回事.它似乎只是得到了正确的数据.我并不是说它是正确的.
内容总结
以上是互联网集市为您收集整理的C#delegate中的Marshal va_list全部内容,希望文章能够帮你解决C#delegate中的Marshal va_list所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。