求助:C# 调用C++的dll的回调函数的结构体数组的问题,为什么只得到数组的一条记录。

2025-01-12 14:12:52
推荐回答(2个)
回答1:

关键是 lpOnRecvCardEvent 这个函数的第二个参数是个 C++ 指针。
楼主在 C# 中声明这个导出函数时,使用了并不对应的 CardEvent[] C# 数组类型。
正确的做法是: 在 C# 声明 lpOnRecvCardEvent 时,第二个参数应该是 IntPtr ,不是数组。
由于楼主的这个 VC DLL 可能是自己写的,我没办法给出正确代码。
我提供一份模拟代码做参考:
----------------------------------------------------------------------------------------------------
VC DLL:
StructMod.h

#pragma once

#include

#ifndef STRUCTMOD_EXPORT
#define STRUCTMOD_EXPORT extern "C" __declspec(dllimport)
#endif

typedef struct _tagCardEvent {
DWORD CardNo;
INT32 EvtYear;
} CardEvent, *PCardEvent;

STRUCTMOD_EXPORT CardEvent;
STRUCTMOD_EXPORT PCardEvent;

typedef void CALLBACK PFNTEST(PCardEvent pce, INT32 nEvt);

STRUCTMOD_EXPORT void Caller(PFNTEST pfnTest);

StructMod.cpp

#define STRUCTMOD_EXPORT extern "C" __declspec(dllexport)
#include "StructMod.h"
#include

void Caller(PFNTEST pfnTest) {
CardEvent ce[2] = { { 2, 2011 }, { 3, 2005 } };
if (pfnTest) (*pfnTest)(ce, _countof(ce));
}

--------------------------------------------------------------------------------------------------------------------
C# 调用:

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace IntPtrTest
{
class Program
{
static void Main(string[] args)
{
TestD t = new TestD(Test);
Caller(t);
}

[StructLayout(LayoutKind.Sequential)]
public struct CardEvent
{
public uint CardNo;
public Int32 EvtYear;
}

delegate void TestD(IntPtr p, Int32 nEvt);
[DllImport("StructMod", EntryPoint = "Caller", CallingConvention = CallingConvention.Cdecl)]
private static extern void Caller(TestD t);

public static unsafe void Test(IntPtr p, Int32 nEvt)
{

Console.WriteLine("nEvt = " + nEvt.ToString() + Environment.NewLine);
for (int n = 0; n < nEvt; n++)
{
p = p + n * sizeof(CardEvent);
CardEvent ce = (CardEvent)Marshal.PtrToStructure(p, typeof(CardEvent));
Console.WriteLine("[{0}]", n);
Console.WriteLine("CardNo - " + ce.CardNo.ToString());
Console.WriteLine("EvtYear - " + ce.EvtYear.ToString());
}
}
}
}

回答2:

以前写过类似的,可以私下交流么?
应该在函数中加个参数,用来记录读取的数据位置。每次调用回调函数的时候就会取到不同的数据