2017-09-21 10 views
0

私は、C#プロジェクトでインポートしたいC++の多くの検証コードを含む巨大なC++構造体を持っています。私はCHAR *とCHAR []以外のすべての値を転送することができます。 CHARの*付きC++からC#への文字配列の受け渡し

、私の文字列がchinessのcaracterいっぱいですが、私はメモリ内のルックを行けば、私の文字列があると、私は、「これはテスト#1である」を参照してくださいすることができます。 CHARと

[x]は、私は、メモリ内の同じだけ1rstチャーを、見ることができます。以下の試験において

、Iは、整数を抽出することができる: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(); 

    } 
    } 
+0

Hanziは、ASCIIテキストをUTF-16が必要なものに渡していることを示唆しています。 P/Invokeでは、テキストの種類を指定できます。 – chris

+0

C#側では、あなたの安全でない構造体では、 'char'の代わりに' byte'を使い、 'Encoding.Default.GetString'を使ってテキストに変換してください。 –

答えて

0

私はそれを見つけた[OK]を、私は、構造体宣言

/* 
     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; 
関連する問題