C# DLL in Inno Setup Access Violation

I'm trying to reference a C# DLL in my InnoSetup project. What I need is a simple function with one string parameter and a string return value. But even following the example and trying different kinds of marshaling I always end up in a Access Violation.

This is my C# class :

public class NKToolbox
{
    [DllExport("EncryptPassword", CallingConvention.StdCall)]
    static string EncryptPassword([MarshalAs(UnmanagedType.LPStr)] string password)
    {
        File.WriteAllText(@"C:temptest.txt", password);
        return password.Length.ToString();
    }       
}

I placed the File.WriteAllText to see if the method is even called. But no. I Use the UnmanagedExports package from Robert Giesecke.

And the Inno Setup Code :

function EncryptPassword(pw: WideString): WideString;
external 'EncryptPassword@files:nktoolbox.dll stdcall';

function InitializeSetup: Boolean;
var
  str: WideString;
begin
  str := EncryptPassword('sdvadfva');
  log(str);
  result := False;
end;

On the line str := EncryptPassword('sdvadfva') I get a 'Access violation at address ...... Write of address .....' I'm using Inno Setup 5.5.9 Unicode.

I've tried it with different marshaling statements I've found in other threads, I've tried it with the out keyword, with normal string type and WideString hopeless.


[DllExport("EncryptPassword", CallingConvention.StdCall)]
static string EncryptPassword([MarshalAs(UnmanagedType.LPStr)] string password)

In Delphi code, this maps to:

function EncryptPassword(password: PAnsiChar): PAnsiChar; stdcall;

Note also that the C# code returns a string allocated by a call to CoTaskMemAlloc . Your code is expected to deallocate that buffer by calling CoTaskMemFree .

Your code that imports this function attempts to treat the text as COM BSTR strings. That's just not the case.

Using COM BSTR , aka WideString is a good idea. But be warned that there is likely a mismatch between the C# and Inno assumed ABI for return values. Better to use an out parameter. See Why can a WideString not be used as a function return value for interop?

In your shoes I would declare the C# like so:

[DllExport("EncryptPassword", CallingConvention.StdCall)]
static void EncryptPassword(
    [MarshalAs(UnmanagedType.BStr)] 
    string input
    [MarshalAs(UnmanagedType.BStr)] 
    out string output
)
{
    output = ...;
}       

And the Inno would be like so:

procedure EncryptPassword(input: WideString; out output: WideString);
  external 'EncryptPassword@files:nktoolbox.dll stdcall';

I know nothing of Inno so that part of my answer is somewhat reliant on guesswork.

链接地址: http://www.djcxy.com/p/44526.html

上一篇: 在Inno安装程序中导入C#DLL时,“无法导入dll”

下一篇: Inno Setup访问冲突中的C#DLL