各位大哥。
小弟脑细胞都死光了。
现在有两个问题不知道如何解决!
第一:.net里面如何模拟C++中可变参数的行为??
第二:union如何处理 [FieldOffset(0)]似乎不行。因为union里面有char*类型!各位大哥救救我吧!公司要求没有办法!
小弟脑细胞都死光了。
现在有两个问题不知道如何解决!
第一:.net里面如何模拟C++中可变参数的行为??
第二:union如何处理 [FieldOffset(0)]似乎不行。因为union里面有char*类型!各位大哥救救我吧!公司要求没有办法!
.net下有C++还用C#模拟,你们公司是怎么想的
既然只是模拟行为,你写个可变参数方法不就是2、union?你们公司不是想替换C++的某个DLL吧?模拟?
看看给变量加上[MarshalAs(UnmanagedType.XXX)]能否解决把,或者char*用char[]看看~
你用System.Runtime.InteropServices.Marshal.SizeOf()看看结构大小和C++的一致就行了~
你考虑一下,把各种可能出现的情况封成不同的结构,然后做个类似工厂一类的处理类,按对象属性付值操作返回最终对象……
其实C++中的可变参数实质是采用数组实现,C#下可以使用 params 参数实现;另外C++中的default值参数可以在C#中通过重载实现。第二:union如何处理 [FieldOffset(0)]似乎不行。因为union里面有char*类型!
这个问题其实有很多的解决方案,[FieldOffset(0)]只是指定该变量的相对偏移而已,还必须配合其他Attributes才能实现Union。示例:union MYUNION2
{
int i;
char str[128]; //char* szStr
}; ||
\/[StructLayout( LayoutKind.Explicit, Size=128 )]
public struct MyUnion2_1
{
[ FieldOffset( 0 )]
public int i;
}OR[ StructLayout( LayoutKind.Sequential )]
public struct MyUnion2_2
{
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]
public String str;
}
unsafe{
//unsafe code here.
}
你的方法很好,不过....
我并不知道char* 的确切大小 在C++中这只是一个4位的指针
而在.net中这是一个Byte的数组而且是一个长度不知道的数组。
如果那样的话就只能这样了:
使用IntPtr得到Union的内存,自己手工用Marshal读取其中的内容,即所有使用Union的地方都替换成IntPtr调用,这样是最保险的,也是最灵活的,前提是自己知道Union中的存储分布情况。困了,改天在来看看。
union MYUNION2
{
int i;
char* szStr
};HRESULT WINAPI SomeApiFunc(/*[in, out]/*MYUNION2* pData);
||
\ /
\/[StructLayout( LayoutKind.Sequence )]
public struct MyUnion2_1
{
//[ FieldOffset( 0 )]
//public int i;
[ FieldOffset( 0 )]
public IntPtr szStr
}[DllImport("DllName.dll"]
public static extern int SomeApiFunc(ref MyUnion2_1 data);//Uasage
//...
{ MyUnion2_1 data = new MyUnion2_1();
SomeApiFunc(ref pData);
IntPtr pszStr = data.szStr;
string wewantedString = Marshal.PtrToStringAuto (pszStr) ; //...
}
//...
{
int i;
char* szStr
};HRESULT WINAPI SomeApiFunc(/*[in, out]/*MYUNION2* pData);[ StructLayout( LayoutKind.Sequential )]
public struct MyUnion
{
[ FieldOffset( 0 )]
public int i;
[ FieldOffset( 0 )]
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]
public StringBuilder str;
}