当前位置:编程学习 > C#/ASP.NET >>

小弟要用C#调用C++写的dll,现在调用报错,说是参数不对,请众位大虾指点!!谢谢!!!只剩58分了可用了,别嫌分少

--------------------编程问答-------------------- 我自己顶起!大虾们帮帮忙!!!谢谢了 --------------------编程问答-------------------- 记得以前不是这样做的
首先得定义结构体长度
其次应该把结构体转化成byte数组 --------------------编程问答-------------------- 我自己顶起!大虾们帮帮忙!!!谢谢了 --------------------编程问答-------------------- bobui您好,能把您以前的代码给我参考一下吗? --------------------编程问答-------------------- 我自己顶起!大虾们帮帮忙!!!谢谢了 --------------------编程问答-------------------- 你的代码太多,自己看看这篇文章吧http://msdn.microsoft.com/zh-cn/library/aa288468%28VS.71%29.aspx --------------------编程问答-------------------- http://msdn.microsoft.com/zh-cn/library/aa288468%28VS.71%29.aspx
此文章已看过,对我有一些帮助(比如:[MarshalAs(UnmanagedType.ByValTStr, SizeConst=LF_FACESIZE)]
),但我这里的C++定义的数据结构是struct内包含struct的,比较复杂。

我正在调整、测试中,但还是想请大虾们出手帮帮忙!!

--------------------编程问答-------------------- 楼主,你第一个结构体最后那个数组有问题吧:

       pPosItems ItemsInfo[XXX];   // Vendors need to decide 

XXX是什么意思? --------------------编程问答-------------------- 楼主,你那样转换错的太多了,我暂且把第一个结构体的最后一句当成这样:PosItems ItemsInfo[2];

完整解决:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Pos 

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
public String POSID;
public char TransactionType;TransactionType
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public String TransactionNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
public String TransactionDate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
public String TransactionTime;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 31)]
public String CashierName;
public Int32  SiteID;  
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
public String SiteName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public String NozzleNum;
public Int32  ItemCount;  
public Single  TotalAmount;  
public Single  InvoiceAmount;  
public Single  DiscountAmount;  
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
public String Extra1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
public String Extra2;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
public String Extra3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public PosItems[] ItemsInfo;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PosItems 

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public String ItemCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
public String ItemName;
public Single  ItemQuantity;  
public Single  UnitPrice;  
public Single  ItemAmount;  
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
public String Extra1;


函数映射:
        [DllImport("invoice.dll", EntryPoint="Tax_Invoice",CharSet = CharSet.Ansi)]
        public static extern int Tax_Invoice(ref Pos val);//不知你为何突然变成PosInvoice ,让人不可思议! --------------------编程问答--------------------
引用 5 楼 liuyongxu 的回复:
我自己顶起!大虾们帮帮忙!!!谢谢了


不错应该试试 --------------------编程问答--------------------
引用 6 楼 whycom 的回复:
你的代码太多,自己看看这篇文章吧http://msdn.microsoft.com/zh-cn/library/aa288468%28VS.71%29.aspx

不错应该试试 --------------------编程问答-------------------- 根据LZ的问题感觉是
字节大小不一致 --------------------编程问答-------------------- 非常感谢sdl2005lyx !!!!!
正在测试中 --------------------编程问答-------------------- 各位大虾现在的问题是这样的
C#结构定义已经改为:

public struct Pos
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=3)]
public string POSID;//2+1 POS机编号

public char TransactionType;// 交易类型 S Sale R Return

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=11)]
public string TransactionNumber;//10+1 交易流水号

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=9)]
public string TransactionDate;//8+1 打印日期CCYYMMDD

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=7)]
public string TransactionTime;//6+1 打印时间HHMMSS

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=31)]
public string CashierName;//30+1 收银员

public Int32 SiteID;// 加油站编码

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=41)]
public string SiteName;//40+1 加油站名称

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=5)]
public string NozzleNum;//4+1 油枪号

public Int32 ItemCount;// 商品项目数量

public Single TotalAmount;// 应收金额
public Single InvoiceAmount;// 实收金额
public Single DiscountAmount;// 优惠金额

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=41)]
public string Extra1;

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=41)]
public string Extra2;

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=41)]
public string Extra3;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=1)]
public PosItems[] ItemsInfo;//明细数据

}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PosItems
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string ItemCode;//15+1 商品编码

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
public string ItemName;//40+1 商品名称

public Single ItemQuantity;// 商品数量
public Single UnitPrice;// 商品单价
public Single ItemAmount;// 商品小计金额

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
public string Extra1;//20+1 备用1
}


现在的问题是如何为Pos及PosItems赋值?如何调用C++中定义的Tax_Invoice (Pos *pPos)??

我现在是如下操作的:

public Pos makeval()
{
Pos reval = new Pos();

reval.POSID = "12";// = POSID// POS机编号
reval.TransactionType = 'S';//  交易类型
reval.TransactionNumber = "12345678";// 交易流水号
reval.TransactionDate = "20090603";// 打印日期
reval.TransactionTime = "130721";//打印时间
reval.CashierName = "收银";//收银员
reval.SiteID = 100;
reval.SiteName = "站点名称";
reval.NozzleNum = "1234";
reval.ItemCount = 1;// 商品项目数量
reval.TotalAmount = 150.00f;// 应收金额
reval.InvoiceAmount = 120.00f;// 实收金额
reval.DiscountAmount = 30.00f;// 优惠金额

reval.Extra1 = "备注1";
reval.Extra2 = "";
reval.Extra3 = "";

#region  商品明细_开始

PosItems[] item = new PosItems[1];//明细数据

item[0].ItemCode = "12345";//vItemCode;
item[0].ItemName = "商品名称";//vItemName;
item[0].ItemQuantity = 30.0f;
item[0].UnitPrice = 50.0f;
item[0].ItemAmount = 150.0f;
item[0].Extra1 = "备注1明细";

#endregion  商品明细_结束

reval.ItemsInfo = new PosInvoiceItemsA[1];//为Pos中的PosItems初始化并赋值
reval.ItemsInfo[0] = item[0];

return reval;
}


调用方法改为:

[DllImport("auto_invoice.dll", EntryPoint="Tax_Invoice",CharSet = CharSet.Ansi)]
static extern int Tax_Invoice(ref Pos val);

void Button1Click(object sender, System.EventArgs e)
{
Pos pPos = new Pos();
pPos = this.makeval();
i = MainForm.Tax_Invoice(ref pPos);



调用时报错 --------------------编程问答-------------------- 我自己顶起来 --------------------编程问答--------------------
引用 14 楼 liuyongxu 的回复:
各位大虾现在的问题是这样的
C#结构定义已经改为:
C# code

        public struct Pos
        {
            [MarshalAs(UnmanagedType.ByValTStr,SizeConst=3)]
            public string POSID;//2+1    POS机编号
            
   ……

报什么错?你编码有问题吗? --------------------编程问答-------------------- 代码太长!!!  错误说参数有问题?!!?
那就只能是数量和类型有冲突。。 好好看看!!! --------------------编程问答-------------------- 我自己顶起来

我自己有两个疑问:
1、

    typedef struct
    {
        char    POSID[POSID_LEN+1];        //POSID
        char    TransactionType;        //transaction type
        char    TransactionNumber[TRS_NO_LEN+1];//transaction serial number
        char    TransactionDate[TRS_DATE _LEN + 1];//transaction date
        char    TransactionTime[TRS_TIME _LEN + 1];//transaction time
        char    CashierName[CASHIER_NAME_LEN +1];//cashier name
        int     SiteID;                //site ID
        char    SiteName[SITENAME_NAME_LEN +1];    //site name
        char    NozzleNum[NOZZLE_NO_LEN +1];    //nozzle number
        int     ItemCount;            //item count
        float    TotalAmount;            //total amount
        float    InvoiceAmount;              //actual received amount
        float    DiscountAmount;            //discount amount
        char    Extra1[BACK_UP_LEN + 1];    //backup field
        char    Extra2[BACK_UP_LEN + 1];    // backup field
        char    Extra3[BACK_UP_LEN + 1];    // backup field
        pPosItems ItemsInfo[XXX];   // Vendors need to decide 
    } Pos, *pPos;

    typedef struct
    {
        char    POSID[POSID_LEN+1];        //POSID
        char    TransactionType;        //transaction type
        char    TransactionNumber[TRS_NO_LEN+1];//transaction serial number
        char    TransactionDate[TRS_DATE _LEN + 1];//transaction date
        char    TransactionTime[TRS_TIME _LEN + 1];//transaction time
        char    CashierName[CASHIER_NAME_LEN +1];//cashier name
        int     SiteID;                //site ID
        char    SiteName[SITENAME_NAME_LEN +1];    //site name
        char    NozzleNum[NOZZLE_NO_LEN +1];    //nozzle number
        int     ItemCount;            //item count
        float    TotalAmount;            //total amount
        float    InvoiceAmount;              //actual received amount
        float    DiscountAmount;            //discount amount
        char    Extra1[BACK_UP_LEN + 1];    //backup field
        char    Extra2[BACK_UP_LEN + 1];    // backup field
        char    Extra3[BACK_UP_LEN + 1];    // backup field
        pPosItems ItemsInfo[XXX];   // Vendors need to decide 
    } Pos;//去掉了 *pPos
有什么区别??


2、我看见有的例子中是用IntPtr在C#中给c++定义的方法中的参数赋值的。是不是我这个也要用IntPtr这种方法给参数赋值?
特别是我这个参数自身是个结构,但结构中的某个参数又是一个结构数组。调用及赋值方法是不是有些特殊? --------------------编程问答-------------------- 我自己顶起来 --------------------编程问答-------------------- 我给你一个建议,要求编写c++ dlld的人提供一套经过严格测试的c#类库。否则谁主张用c++谁去实现它。 --------------------编程问答-------------------- 楼主,回答你几个问题:
1、“去掉了 *pPos”,这个没有任何关系和影响,判断调用只关心两边的结构体大小和顺序是否一致,别名无关紧要!

2、用IntPtr当然可以,只是增加解析复杂度,要用到Marshal类进行转换!对应有明确类型定义的数据结构,参数封送直接用具体类型为好!除非碰到void*这种类型,必须使用IntPtr。

3、“          [MarshalAs(UnmanagedType.ByValArray,SizeConst=1)]
            public PosItems[] ItemsInfo;//明细数据”
如果你这里只用到1个成员,就不要定义为数组,直接用成员变量即可!
但是你的C++代码:pPosItems ItemsInfo[XXX];   // Vendors need to decide 
让人无法判断!

4、其实这个结构体并不怎么复杂,只有成员很多而已!这样容易是开发人员犯简单错误。经常会出现调用错误:试图读写受保护的内存!大多由两边结构不一致导致!对付这种问题,一个最直接的方法:

在C++那边用sizeof()看看大小为多少!
在C#这部用Marshal.Sizof(Type)看看大小为多少!
发现两边大小不一致,楼主你就仔细检查,一项一项来!别人有时无法代替!


--------------------编程问答-------------------- 谢谢众位!上楼这位大虾的话让我收益非浅!! --------------------编程问答-------------------- 正在测试中

还请其它大虾继续给予指点!! --------------------编程问答-------------------- 现在报错信息为:
调试器抛出异常 System.AccessViolationException:
尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 --------------------编程问答-------------------- c#调用c++的? --------------------编程问答--------------------
引用 24 楼 liuyongxu 的回复:
现在报错信息为:
调试器抛出异常 System.AccessViolationException:
尝试读取或写入受保护的内存。这通常指示其他内存已损坏。


楼主,这是参数封送常见错误,由于你的结构体太长,别人一下不好帮你定位!
不知你用我给你的方法没有:
1、比较两边结构体的大小,看是否一致!
2、先在两边屏蔽一些结构体成员测试,当然逐步放开。 --------------------编程问答-------------------- 十分的混乱。而且你数据结构中的最后一项没有指定大小,如果你不指定大小,那么你应该定义为指针,而不是数组。

 C# code
 [MarshalAs(UnmanagedType.ByValArray,SizeConst=1)]
            public PosItems[] ItemsInfo;//明细数据
--------------------编程问答-------------------- 我自己顶起来 --------------------编程问答-------------------- 谢谢大家!!!
一、C++中结构定义为

    #define POSID_LEN        2    //POSID length
    #define TRS_NO_LEN           10    //transaction serial number length
    #define CASHIER_NAME_LEN    30    //cashier name length
    #define SITENAME_NAME_LEN    40    //site name length
    #define NOZZLE_NO_LEN        4    //nozzle number length
    #define BACK_UP_LEN        40    //backup field length
    #define ITEM_CODE_LEN        15    //item code length
    #define ITEM_NAME_LEN        40    //item name length
    #define TRS_DATE _LEN        8    //Transaction date length
    #define TRS_TIME _LEN        6    //Transaction date length
    #define ITEM_BACK_UP_LEN    20  //Item backup field length
    typedef struct
    {
        char    POSID[POSID_LEN+1];        //POSID
        char    TransactionType;        //transaction type
        char    TransactionNumber[TRS_NO_LEN+1];//transaction serial number
        char    TransactionDate[TRS_DATE _LEN + 1];//transaction date
        char    TransactionTime[TRS_TIME _LEN + 1];//transaction time
        char    CashierName[CASHIER_NAME_LEN +1];//cashier name
        int     SiteID;                //site ID
        char    SiteName[SITENAME_NAME_LEN +1];    //site name
        char    NozzleNum[NOZZLE_NO_LEN +1];    //nozzle number
        int     ItemCount;            //item count
        float    TotalAmount;            //total amount
        float    InvoiceAmount;              //actual received amount
        float    DiscountAmount;            //discount amount
        char    Extra1[BACK_UP_LEN + 1];    //backup field
        char    Extra2[BACK_UP_LEN + 1];    // backup field
        char    Extra3[BACK_UP_LEN + 1];    // backup field
        pPosInvoiceItems ItemsInfo[255];   // Vendors need to decide 
    } PosInvoice, *pPos;
    
    typedef struct  
    {
        char    ItemCode[ITEM_CODE_LEN+1];    //item code
        char    ItemName[ITEM_NAME_LEN+1];    //item name
        float    ItemQuantity;            //item quantity
        float    UnitPrice;            //unit price
        float    ItemAmount;            //item amount
        char    Extra1[ITEM_BACK_UP_LEN+1];    //backup field
    } PosInvoiceItems, *pPosInvoiceItems;

    命令函数:int Tax_Invoice (Pos *pPos)


C#中结构定义为

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PosInvoice
{
[MarshalAs(UnmanagedType.ByValArray,SizeConst=3)]
public byte[] POSID;//2+1 POS机编号

public char TransactionType;// 交易类型 S Sale R Return

[MarshalAs(UnmanagedType.ByValArray,SizeConst=11)]
public byte[] TransactionNumber;//10+1 交易流水号

[MarshalAs(UnmanagedType.ByValArray,SizeConst=9)]
public byte[] TransactionDate;//8+1 打印日期CCYYMMDD

[MarshalAs(UnmanagedType.ByValArray,SizeConst=7)]
public byte[] TransactionTime;//6+1 打印时间HHMMSS

[MarshalAs(UnmanagedType.ByValArray,SizeConst=31)]
public byte[] CashierName;//30+1 收银员

public Int32 SiteID;// 加油站编码

[MarshalAs(UnmanagedType.ByValArray,SizeConst=41)]
public byte[] SiteName;//40+1 加油站名称

[MarshalAs(UnmanagedType.ByValArray,SizeConst=5)]
public byte[] NozzleNum;//4+1 油枪号

public Int32 ItemCount;// 商品项目数量

public Single TotalAmount;// 应收金额
public Single InvoiceAmount;// 实收金额
public Single DiscountAmount;// 优惠金额

[MarshalAs(UnmanagedType.ByValArray,SizeConst=41)]
public byte[] Extra1;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=41)]
public byte[] Extra2;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=41)]
public byte[] Extra3;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=255)]
public PosInvoiceItems[] ItemsInfo;//明细数据

}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PosInvoiceItems
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] ItemCode;//15+1 商品编码

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 41)]
public byte[] ItemName;//40+1 商品名称

public Single ItemQuantity;// 商品数量
public Single UnitPrice;// 商品单价
public Single ItemAmount;// 商品小计金额

// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)]
public byte[] Extra1;//20+1 备用1
}

C#中对结构赋值为

public PosInvoiceA makevalA()
{
PosInvoiceA reval = new PosInvoiceA();


reval.POSID = new byte[3];
Array.Copy(this.String2Bytes("29"),reval.POSID,this.String2Bytes("29").Length);


reval.TransactionType = 'S';


reval.TransactionNumber = new byte[11];
Array.Copy(this.String2Bytes("20000009"),reval.TransactionNumber,this.String2Bytes("20000009").Length);

reval.TransactionDate = new byte[9];
Array.Copy(this.String2Bytes("20110711"),reval.TransactionDate,this.String2Bytes("20110711").Length);

reval.TransactionTime = new byte[7];
Array.Copy(this.String2Bytes("161718"),reval.TransactionTime,this.String2Bytes("161718").Length);

reval.CashierName = new byte[31];
Array.Copy(this.String2Bytes("按擦剂威武"),reval.CashierName,this.String2Bytes("按擦剂威武").Length);

reval.SiteID = 100;// 加油站编码

reval.SiteName = new byte[41];
Array.Copy(this.String2Bytes("加油站名称:刘某人的油站"),reval.SiteName,this.String2Bytes("加油站名称:刘某人的油站").Length);

reval.NozzleNum = new byte[5];
Array.Copy(this.String2Bytes("9118"),reval.NozzleNum,this.String2Bytes("9118").Length);

reval.ItemCount = 1;// 商品项目数量
reval.TotalAmount = 123.45f;// 应收金额
reval.InvoiceAmount = 100.12f;// 实收金额
reval.DiscountAmount = 23.33f;// 优惠金额

reval.Extra1 = new byte[41];
Array.Copy(this.String2Bytes("备用1"),reval.Extra1,this.String2Bytes("备用1").Length);

reval.Extra2 = new byte[41];

reval.Extra3 = new byte[41];

#region  商品明细_开始


PosInvoiceItemsA[] item = new PosInvoiceItemsA[1];//明细数据

item[0].ItemCode = new byte[16];
Array.Copy(this.String2Bytes("16898"),item[0].ItemCode,this.String2Bytes("16898").Length);

item[0].ItemName = new byte[41];
Array.Copy(this.String2Bytes("商品名称"),item[0].ItemName,this.String2Bytes("商品名称").Length);

item[0].ItemQuantity = 30.0f;
item[0].UnitPrice = 50.0f;
item[0].ItemAmount = Convert.ToSingle(150.0f);

item[0].Extra1 = new byte[21];
Array.Copy(this.String2Bytes("商品备注"),item[0].Extra1,this.String2Bytes("商品备注").Length);

#endregion  商品明细_结束

reval.ItemsInfo = new PosInvoiceItemsA[255];
reval.ItemsInfo[0] = item[0];

return reval;
}

C#调用代码为

[DllImport("auto_invoice.dll", EntryPoint="Tax_Invoice",CharSet = CharSet.Ansi)]
static extern int Tax_Invoice(ref PosInvoice val);

void Button1Click(object sender, System.EventArgs e)
{
int i = MainForm.Tax_Connection();

if (i==0)
{
i=255;


PosInvoice pPos = new PosInvoice();
pPos = this.makeval();
int k = Marshal.SizeOf(pPos);//24736

i = MainForm.Tax_Invoice(ref pPos);
MessageBox.Show(i.ToString());
}
else
MessageBox.Show("连接失败"+i.ToString());

}
--------------------编程问答-------------------- 测试时还用另一种方式定义为C#中的结构:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PosInvoice
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=3)]
public string POSID;//2+1 POS机编号

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=1)]
public string TransactionType;// 交易类型 S Sale R Return

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=11)]
public string TransactionNumber;//10+1 交易流水号

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=9)]
public string TransactionDate;//8+1 打印日期CCYYMMDD

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=7)]
public string TransactionTime;//6+1 打印时间HHMMSS

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=31)]
public string CashierName;//30+1 收银员

public Int32 SiteID;// 加油站编码

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=41)]
public string SiteName;//40+1 加油站名称

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=5)]
public string NozzleNum;//4+1 油枪号

public Int32 ItemCount;// 商品项目数量

public Single TotalAmount;// 应收金额
public Single InvoiceAmount;// 实收金额
public Single DiscountAmount;// 优惠金额

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=41)]
public string Extra1;

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=41)]
public string Extra2;

[MarshalAs(UnmanagedType.ByValTStr,SizeConst=41)]
public string Extra3;

[MarshalAs(UnmanagedType.ByValArray,SizeConst=255)]
public PosInvoiceItems[] ItemsInfo;//明细数据

}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PosInvoiceItems
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string ItemCode;//15+1 商品编码

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)]
public string ItemName;//40+1 商品名称

public Single ItemQuantity;// 商品数量
public Single UnitPrice;// 商品单价
public Single ItemAmount;// 商品小计金额

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)]
public string Extra1;//20+1 备用1
}

补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,