将 char 数组值从 C++ 传递到 C# 应用程序

Pass char array value from C++ to C# app

我有一个巨大的 C++ 结构,其中包含大量 C++ 验证代码,我想将其导入到 C# 项目中。我能够传输除 CHAR* 和 CHAR[] 之外的所有值。

使用 CHAR*,我的字符串充满了中文字符 但是,如果我去内存中查找,我的字符串就在那里,我可以看到 "This is a test #1"。

对于 CHAR[x],我只能看到第一个字符,与内存中相同。

在下面的测试中,我可以提取整数:value1 = data.Value1; 值 1 是 123,但是 CHAR.

问题:我想念的是,为什么我无法使用 char 数组获取值。 谢谢

C++ DLL

//This is the main DLL file.
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>

extern "C"
{
  public struct Data
  {
    int Value1;
    char* pValue2;
    char Value3[1024];
  };

  typedef int( *FN_CCP_INVOKE_NEW_BOARD_OPTIMIZER) (struct Data* data);

  FN_CCP_INVOKE_NEW_BOARD_OPTIMIZER _pInvokeCallback;

  int __declspec(dllexport)  DLLTestCPlusPlus_Initialize()
  {
    return 0;
  }

  int __declspec(dllexport) DLLTestCPlusPlus_RegisterDllInvokeProcessCallback(void* fnInvokeCaller)
  {
    _pInvokeCallback = (FN_CCP_INVOKE_NEW_BOARD_OPTIMIZER)fnInvokeCaller;

    struct Data data;

    // INT
    data.Value1 = 123;

    // CHAR*
    data.pValue2 = new char[1024];
    sprintf(data.pValue2, "This is a test #1");

    // CHAR [1024]
    sprintf(data.Value3, "This is a test #2");

    if (_pInvokeCallback)
    {
      _pInvokeCallback(&data);
    }

    return 0;
  }
}

这里是导入 DLL 的 C# 程序。

using System;
using System.Runtime.InteropServices;

  public unsafe struct Data
  {
    public int Value1;
    public char* pValue2;
    public fixed char Value3[1024];
  }

  public static class Interop
  {
    public delegate Int32 Callback([MarshalAs(UnmanagedType.Struct)] Data data);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool SetDllDirectory(string lpPathName);


    [DllImport("C:\DATA\CODE\ApplicationTestCSharp\x64\Debug\DLLTestCPlusPlus.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern Int32 DLLTestCPlusPlus_Initialize();

    [DllImport("C:\DATA\CODE\ApplicationTestCSharp\x64\Debug\DLLTestCPlusPlus.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern Int32 DLLTestCPlusPlus_RegisterDllInvokeProcessCallback([MarshalAs(UnmanagedType.FunctionPtr)] Callback handler);
  }

  public class MyTest
  {
    private Interop.Callback _callback = null;

    public MyTest()
    {
      int returnCode = 0;

      returnCode = Interop.DLLTestCPlusPlus_Initialize();

      _callback = new Interop.Callback(CallbackHandler);

      returnCode = Interop.DLLTestCPlusPlus_RegisterDllInvokeProcessCallback(_callback);
    }

    private Int32 CallbackHandler(Data data)
    {
      int value1 = 0;
      string value2 = "";
      string value3 = "";

      unsafe
      {
        // INT
        value1 = data.Value1;

        // CHAR* - MUST BE "This is a test #1"
        value2 = new string(data.pValue2);

        // CHAR [1024] - "This is a test #2"
        value3 = new string(data.Value3);
      }

      return 1;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      MyTest myTest = new MyTest();

    }
  }

好的,我找到了,我在结构声明中进行了更改

   /*
      public char* pValue2;
      public fixed char Value3[1024];
      */
      [MarshalAs(UnmanagedType.LPStr)] public String pValue2;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] public String pValue3;

然后像那样提取数据!

  // CHAR* - "This is a test #1";
  // value2 = new string(data.pValue2);
     value2 = data.pValue2

  // CHAR [1024] - "This is a test #2"
  //value3 = new string(data.Value3);
    value3 = data.pValue3;