2013-06-11 2 views
4

이 내가 주소 구조를 전달하여이 API를 호출 할 C#을에서 C 내 구조와 기능 ++ DLLC에 C#을 구조의 포인터를 전달 ++ API

struct Address 
{ 
    TCHAR* szAddress; 
}; 

extern "C" DllExport void SetAddress(Address* addr); 

입니다. 그래서, 나는 내가 C++ 코드에서 Address.szAddress에 대한 NULL 무엇입니까 C#

Address addr = new Address(); 
addr.addressName = "Some Address"; 
IntPtr pAddr = Marshal.AllocHGlobal(Marshal.SizeOf(addr)); 
Marshal.StructureToPtr(addr , pAddr , false); 
SetAddress(pAddr); //CALLING HERE 

에서 C++ API를 호출하고 어떻게이 지금

[StructLayout(LayoutKind.Sequential)] 
public struct Address 
{ 
    [MarshalAs(UnmanagedType.LPTStr)] 
    public String addressName; 
} 

[DllImport("Sample.dll")] 
extern static void SetAddress(IntPtr addr); 

C#

을에서 다음했다. 어떤 생각이 잘못된 것입니까?

+1

[DllImport] 선언에 CallingConvention.Cdecl이 없습니다. –

+0

이것을 사용하고 CallingConvention = CallingConvention.Winapi를 시도하십시오. –

답변

6

구조체를 ref에 전달하면됩니다. 또한 호출 규칙이 일치해야합니다. 네이티브 코드가 cdecl 인 것처럼 보입니다. 마지막으로 UnmanagedType.LPTStr은 Win9x 및 유니 코드의 ANSI를 의미합니다. 따라서 네이티브 코드가 UTF-16 문자열을 필요로하는 경우에 적합합니다. ANSI가 필요한 경우 대신 UnmanagedType.LPStr을 사용하십시오.

이 코드는 올바르게 작동하며 C# 코드에 지정된 문자열이 기본 코드에 의해 수신됩니다.

[StructLayout(LayoutKind.Sequential)] 
public struct Address 
{ 
    [MarshalAs(UnmanagedType.LPTStr)] 
    public string addressName; 
} 

[DllImport(@"test.dll", CallingConvention=CallingConvention.Cdecl)] 
extern static void SetAddress(ref Address addr); 

static void Main(string[] args) 
{ 
    Address addr; 
    addr.addressName = "boo"; 
    SetAddress(ref addr); 
}