2015-12-17 29 views
0

我有以下代码:访问冲突异常由第二接入访问C DLL功能

Generic.cs
class Generic 
{ 
    [DllImport("Generic.dll", EntryPoint = "Consult", CallingConvention = CallingConvention.Winapi)] 
    public static extern String Consulta(int NumeroSecao);  
} 

而且

main.cs
private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    Random rnd = new Random(); 
    int random = rnd.Next(9999); 
    Stopwatch sw = new Stopwatch(); 

    sw.Start(); 
    String teste = Generic.Consult(random); 
    sw.Stop(); 

    TextoLog = "Tempo de Execução:"+sw.Elapsed.Milliseconds+"ms | ConsultarSAT"; 
    tempoEntreComandos(); 
} 

的DLL的代码是:

GENERIC.C

__declspec(dllexport) char* __stdcall Consult(int numeroSessao) 
{ 
    memset(pcReturn,0,sizeof(char) * BUFFER_SIZE); 
    HANDLE fileHandle; 
    Communicate(&fileHandle, pcReturn,10); 
    return pcReturn; 
} 

当我打电话功能Consult所述第二时间,接收的消息是一个Access Violation Exception将出现问题。这里发生了什么?

+0

'的sizeof(char)的'保证是'1'。 – BoBTFish

回答

1

解决方法是在函数声明中返回的类型,而不是使用String必须使用IntPtr

1

原生字符串必须封送到c#中使用。你的本地代码实际上并不是返回一个字符串对象,而是一个字符指针。你必须告诉封送返回类型是什么,像这样:

[DllImport("Generic.dll", EntryPoint = "Consult", CallingConvention = CallingConvention.Winapi)] 
[return: MarshalAs(UnmanagedType.LPStr)] 
public static extern String Consulta(int NumeroSecao); 

使用LPSTR为ASCII字符串和LPWSTR对Unicode。


其实这可能是一个更好的主意来手动元帅字符串作为封送转换之后将释放本地字符串。该宣言是那么

[DllImport("Generic.dll", EntryPoint = "Consult", CallingConvention = CallingConvention.Winapi)] 
public static extern IntPtr Consulta(int NumeroSecao); 

并手动元帅的IntPtr串像这样

String str = Marshal.PtrToStringAnsi(strptr); // for ansi 
String str = Marshal.PtrToStringUni(strptr); // for unicode