c++的D.dll里定义:typedef struct
{
char a[10];
long b;
}SS;
SS funA(char *p1,long p2);C#里:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct RESULT
{
public byte[] a;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AnsiBStr, SizeConst = 10)]
public int b;
}
[DllImport("D.dll", EntryPoint = "funcA", CharSet = CharSet.Ansi)]
public static extern RESULT func_A(StringBuilder p1,int p2);StringBuilder p1=new StringBuild("fff");
RESULT res = func_A(p1,111);
运行到这儿,直接退出!没有任何提示!请教高手!
谢谢!
{
char a[10];
long b;
}SS;
SS funA(char *p1,long p2);C#里:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct RESULT
{
public byte[] a;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AnsiBStr, SizeConst = 10)]
public int b;
}
[DllImport("D.dll", EntryPoint = "funcA", CharSet = CharSet.Ansi)]
public static extern RESULT func_A(StringBuilder p1,int p2);StringBuilder p1=new StringBuild("fff");
RESULT res = func_A(p1,111);
运行到这儿,直接退出!没有任何提示!请教高手!
谢谢!
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
string a;
public int b;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct RESULT
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AnsiBStr, SizeConst = 10)]
public byte[] a;
public int b;
}
更正二:
上面用struct,出错:“方法的类型签名与 PInvoke 不兼容。”
如果用class,才是“运行到这儿,直接退出!没有任何提示!”
public byte[] a;
我用到的struct作参数时,用这个没问题。改成你上面的样子,只要是struct,就报:“方法的类型签名与 PInvoke 不兼容。”
作为函数返回值时,就不行了!用class,怎么用才不运行到调用方法时,直接退出,没有任何提示??
而不支持类型中含有需分配大小的成员(就像那个[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]string a)。
我看到一些类似的提法,但没有从微软的文档中找到依据。一个变通的方法是把返回的结构成员全部改写成Bittable类型,而用属性来进行自定义转换:// 结构成员都是Blittable,dummy们是占位的傀儡
[StructLayout(LayoutKind.Sequential)]
public struct RESULT
{
public int dummy1, dummy2, dummy3;
public int b; public string a
{
get
{
List<byte> bytes = new List<byte>();
bytes.AddRange( BitConverter.GetBytes(dummy1) );
bytes.AddRange( BitConverter.GetBytes(dummy2) );
bytes.AddRange( BitConverter.GetBytes(dummy3) );
return Encoding.ASCII.GetString(bytes.ToArray(), 0, bytes.IndexOf(0));
}
}
}
朋友们谁有更准确的解释和方法,烦请赐教。
typedef struct
{
char a[10];
long b;
}SS;
怎么做呢?不需要改DLL文件吧(这不可能)?
dummy1, dummy2, dummy3的值怎么来?
为什么是3个?跟char a[10] 有关系吗?
另外,在C#里仍是定义为struct?谢谢
帮你解释一下5楼的意思1、关于dummy1, dummy2, dummy3
5楼说“dummy们是占位的傀儡”,意思就是三个int纯粹是为了占位即申请内存空间而设置的,
你要是高兴,弄上几个short,或者1个1个的byte也无不可2、为什么是3个?跟char a[10] 有关系吗?
有关系。3个int占了12个字节,比你的char a[10]空间大些才能装得下你的char a[10]。
作为string来说,还有个结束符'\0',所以你的char a[10]转为string后最多需要占用到11个字节的空间。
故此,傀儡们事先占好12个字节的空间,以防止空间不足,也没有过多浪费。3、在C#里仍是定义为struct
是的
C#中的三个int也占12个字节。struct不会变成指针的,C#里仍定义为struct。
作为string来说,还有个结束符'\0',所以你的char a[10]转为string后最多需要占用到11个字节的空间。
--->
这里char a[10]转为string后最多需要占用到10个字节的空间。若有'\0'应是在char a[10]内部基于9楼的解释,为5楼的代码再添加点注释// 结构成员都是Blittable,dummy们是占位的傀儡
[StructLayout(LayoutKind.Sequential)]
public struct RESULT
{
public int dummy1, dummy2, dummy3; //申请到12字节内存,用于接收char[10] a
public int b; //申请4字节内存,对应long b public string a //属性a,对应char[10] a,用于外部使用
{
get
{
//外部访问此string a时,把3个dummy里面存储的数据转换为c#里面的string
List<byte> bytes = new List<byte>(); //用于临时存储转换过程中的数据
bytes.AddRange( BitConverter.GetBytes(dummy1) ); //把dummy1按字节存入bytes,下同
bytes.AddRange( BitConverter.GetBytes(dummy2) );
bytes.AddRange( BitConverter.GetBytes(dummy3) ); //把bytes按ASCII码转为字符串并返回
//注意bytes.IndexOf(0)这里的意思是如果字节中有0即'\0',则表示字符串已结束
//这里不太严谨,假设了你的char[10]是作为字符串用的,如果你不是这样子(没'\0'),需要自行处理
return Encoding.ASCII.GetString(bytes.ToArray(), 0, bytes.IndexOf(0));
}
}
}
哈哈,再次更正11楼的更正,忘了字节对齐的事情了关于char a[10]的转换占用空间,以10楼为正解
要建2253个“傀儡”??!!!如果long型能用也要1147个?!
然后在C#中使用 OpenFileMapping 在指定的内存地址获取数据.
要是能修改DLL,就不要这么麻烦了,只要修改返回值类型,把结构变为出参就行了。
返回一个非常大的结构是设计上的失误 - 结构都是按拷贝传参的,拷贝大结构成本不小。
如果一定要做,或许这样(看着难受):
struct A64
{
public long a,b,c,d;
}
struct A256
{
public A64 a,b,c,d;
}另,谢谢agentianle的讲解,比我的生动多了。
struct A32
{
public long a,b,c,d;
}
提供一个思路供参考:鉴于你不能修改c++程序,可以考虑对其进行封装一下。即,可以用c++做个自己的dll,封装、转换原dll的方法。这个代理dll可以起到沟通原dll和C#程序的作用。如此,14楼中所述“可以在C++中使用 CreateFileMapping 将结构体数据直接写进内存, ”即可在代理dll中实现。而你则可 “然后在C#中使用 OpenFileMapping 在指定的内存地址获取数据.”
该书的官方网站:
www.interop123.com 豆瓣网信息:
http://www.douban.com/subject/3671497/