C#调用C++函数,参数是结构体,结构体里再带指针,取不到返回值

时间:2022-08-30 19:13:39
C++
函数原型:
GetPosition(LPCSTR lpMarket, LPCSTR lpCode, HoloPosition *pReqHoloData);
C++结构体声明:
typedef struct _HoloPosition
{
char szMarKet[8];
char szCode[16];

int nSizeOfAskQueue;            
HoloQueueItem *pHeadOfAskQueue; // 返回结构体数组

int nCountOfBidQueue;           
HoloQueueItem *pHeadOfBidQueue; // 返回结构体数组

HoloMarketData marketData;  
}HoloPosition;

typedef struct _HoloQueueItem
{
int  nTime;  
int  nPrice;  
int  nVolume;  
int  nNumOrder;  
}HoloQueueItem;

C#:

函数声明:
public static extern int GetPosition(string lpMarket, string lpCode, ref IntPtr pReqHoloData);
C#结构体声明:
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct HoloPosition
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
        public string chMarket;         
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string chCode;         

        public int nSizeOfAskQueue;             
        public IntPtr pHeadOfAskQueue;          

        public int nCountOfBidQueue;            
        public IntPtr pHeadOfBidQueue;          

        public HoloMarketData marketData;       
    }

    public struct HoloQueueItem
    {
        public int nTime;                 
        public int nPrice;                     
        public int nVolume;                     
        public int nNumOrder;                   
    }


C++函数调用示例

HoloPosition data = {};
GetPosition(m_szCode.Left(2), m_szCode.Right(6), &data))


C#函数调用实现

            HoloPosition pHolo = new HoloPosition();
            pHolo.pHeadOfAskQueue = IntPtr.Zero;
            pHolo.pHeadOfBidQueue = IntPtr.Zero;
            pHolo.marketData = new HoloMarketData();

            IntPtr pData = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HoloPosition)));

            Marshal.StructureToPtr(pHolo, pData, true);

            Ivoke.TDF_GetHoloPosition(strMarket, strCode, ref pData); //内存破坏

pHolo.pHeadOfAskQueue和pHolo.pHeadOfBidQueue的内存是在C++内分配,并返回的。
取不到返回值,总是为0,求大侠指点。

7 个解决方案

#1


结构里有指针的话不建议C#直接调用,可以封装成在C++中调用,序列化这个结构成字符串,在C#中再反序列化这个字符串即可。

#2


c#里杨用指针,得定义成不安全的才行,就是加上_unsafe(好象是这个,你查一下C#如何用指针)

#3


string类型不需要加ref么?

我怎么记得需要呢?

#4


to zyq5949
不是俺家的C++呀,伤心ing......

to hdg3707
C#里面用指针,不是非要设置成_unsafe才行,和C++类似,用IntPtr存放首地址即可。

to tiger9991
参数是in,不需要ref。out才需要ref,传址引用。

#5


即使预先分配内存到结构体变量中,结果还是一样。点解??? C#调用C++函数,参数是结构体,结构体里再带指针,取不到返回值

        private IntPtr InitQueue(int nSize)
        {
            IntPtr pt = IntPtr.Zero;
            int nStructSize = Marshal.SizeOf(typeof(HoloQueueItem));
            if (nSize > 0)
            {
                HoloQueueItem[] queue = new HoloQueueItem[nSize];
                IntPtr[] ptArray = new IntPtr[1];
                ptArray[0] = Marshal.AllocHGlobal(nStructSize * nSize);
                pt = Marshal.AllocHGlobal(nStructSize);
                Marshal.Copy(ptArray, 0, pt, 1);
            }
            return pt;
        }

// 函数调用
            HoloPosition pHolo = new HoloPosition();
            pHolo.pHeadOfAskQueue = InitQueue(2000);
            pHolo.pHeadOfBidQueue = InitQueue(2000);
            pHolo.marketData = new HoloMarketData();

            IntPtr pData = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HoloPosition)));

            Marshal.StructureToPtr(pHolo, pData, true);

            TDF_GetHoloPosition(strMarket, strCode, ref pData);

#6


该回复于2012-11-16 10:49:54被管理员删除

#7


我是说你再用C++再封装一层,就调用前后的序列化和反序列化即可,和你有没有源码没关系。

#1


结构里有指针的话不建议C#直接调用,可以封装成在C++中调用,序列化这个结构成字符串,在C#中再反序列化这个字符串即可。

#2


c#里杨用指针,得定义成不安全的才行,就是加上_unsafe(好象是这个,你查一下C#如何用指针)

#3


string类型不需要加ref么?

我怎么记得需要呢?

#4


to zyq5949
不是俺家的C++呀,伤心ing......

to hdg3707
C#里面用指针,不是非要设置成_unsafe才行,和C++类似,用IntPtr存放首地址即可。

to tiger9991
参数是in,不需要ref。out才需要ref,传址引用。

#5


即使预先分配内存到结构体变量中,结果还是一样。点解??? C#调用C++函数,参数是结构体,结构体里再带指针,取不到返回值

        private IntPtr InitQueue(int nSize)
        {
            IntPtr pt = IntPtr.Zero;
            int nStructSize = Marshal.SizeOf(typeof(HoloQueueItem));
            if (nSize > 0)
            {
                HoloQueueItem[] queue = new HoloQueueItem[nSize];
                IntPtr[] ptArray = new IntPtr[1];
                ptArray[0] = Marshal.AllocHGlobal(nStructSize * nSize);
                pt = Marshal.AllocHGlobal(nStructSize);
                Marshal.Copy(ptArray, 0, pt, 1);
            }
            return pt;
        }

// 函数调用
            HoloPosition pHolo = new HoloPosition();
            pHolo.pHeadOfAskQueue = InitQueue(2000);
            pHolo.pHeadOfBidQueue = InitQueue(2000);
            pHolo.marketData = new HoloMarketData();

            IntPtr pData = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(HoloPosition)));

            Marshal.StructureToPtr(pHolo, pData, true);

            TDF_GetHoloPosition(strMarket, strCode, ref pData);

#6


该回复于2012-11-16 10:49:54被管理员删除

#7


我是说你再用C++再封装一层,就调用前后的序列化和反序列化即可,和你有没有源码没关系。