2015-01-25 1 views
0

나는 C++ dll에서 작동하며 문제가 있습니다! 내 헤더 파일이C# 구조 배열을 C++에 전달

struct ST_DevInfo 
{ 
    EN_DevType de_type;   
    int screen_width;   
    int screen_height;   
    char dev_name[256];   
    char id[14];    
    char sboox_version[16];  
    char fpga_version[16];  
}; 

extern "C" __declspec(dllexport) int CB_GetDeviceList(ST_DevInfo* buff,int length); 

및 C++ 코드

int CB_GetDeviceList(ST_DevInfo* buff,int length) 
{ 
    buff = (ST_DevInfo *)malloc(sizeof(ST_DevInfo) * length); 

    return GetDeviceList(buff, length); 
} 

지금 내가이

[StructLayout(LayoutKind.Sequential)] 
     struct ST_DevInfo 
     { 
      [MarshalAs(UnmanagedType.I4)] 
      public EN_DevType de_type; 
      [MarshalAs(UnmanagedType.I4)] 
      public int screen_width; 
      [MarshalAs(UnmanagedType.I4)] 
      public int screen_height; 
      [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 256)] 
      public char[] dev_name; 
      [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 14)] 
      public char[] id; 
      [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 16)] 
      public char[] sboox_version; 
      [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 16)] 
      public char[] fpga_version; 
     }; 

[DllImport(dllName, EntryPoint = "CB_GetDeviceList", SetLastError = true, ExactSpelling = true, 
      CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] 
     public static extern 
      int CB_GetDeviceList([MarshalAs(UnmanagedType.LPArray)] ref ST_DevInfo[] buff, 
            int length); 

같은 C#에서이 기능을 사용하고 마지막으로 내가 좋아하는 내 프로그램에서이 기능을 사용 같다 이

ST_DevInfo[] buff = new ST_DevInfo[dev_length]; 
int ret = BBIA.CB_GetDeviceList(ref buff, dev_length); 

그러나 검색 후 CB_GetDeviceList 내 buff 변수는 할당되었지만 값 (0x00 포함)이 없습니다. 나는 C++로 테스트하고 잘 작동한다 !! 는 난이 광고

버프 = (ST_DevInfo *)의 malloc (sizeof 연산자 (ST_DevInfo) * 길이)에 문제가 있다고 생각; 당신의 C# 코드에서

+1

이미 할당 된 메모리를 함수에 전달 중이므로 C++ 코드에서 malloc을 제거하십시오. 실제로 새로운 배열에 데이터를 쓰는 중이며 C#에서 전달 된 데이터를 수정하지 마십시오. – Chris

답변

0

당신은이 일을하고 있습니다 :

ST_DevInfo[] buff = new ST_DevInfo[dev_length]; 
int ret = BBIA.CB_GetDeviceList(ref buff, dev_length); 

하는 배열을 할당하고, (당신이 ref이 있기 때문에 이중 포인터)를 C++ 코드에, 그 전달된다. 당신의 C에서

++ 코드 당신이하고 있습니다 : 배열을 취하고있다

int CB_GetDeviceList(ST_DevInfo* buff,int length) 
{ 
    buff = (ST_DevInfo *)malloc(sizeof(ST_DevInfo) * length); 
    return GetDeviceList(buff, length); 
} 

(그리고 이중 포인터 등)과 새로운 메모리를 가리 키도록 그 (지역) 포인터를 변경. 따라서 C#의 원래 배열에는 C++ 코드가 적용되지 않습니다.

먼저 malloc 전화를 완전히 제거하십시오. 그런 다음 핀바크를 다음과 같이 변경하십시오.

[DllImport(...)] 
public static extern int CB_GetDeviceList([In, Out] ST_DevInfo[] buff, int length); 

ref없이 이전과 동일하게 전화하십시오. 마샬 러에게 pinvoke 호출이 데이터 수정을 원한다는 것을 알려주려면 In, Out이 필요합니다. 그들은 모든 경우에 필요하지는 않지만, 귀하의 경우에는 100 % 확신 할 수 없으므로 만약을 대비하여 그들을 계속 지키고 있습니다.