0

I have a C# DLL (.NET 2.0 framework) which is setup as COM Visible.

The Interface is declared as

[Guid("....")]
[InterfaceType(ComInterfaceType.InterfaceIDispatch)]
public interface IMyClass
{
   [DispId(1)]
   string myFunc(string url, ref string[] keys);
}

[Guid("...")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyClass.Lib")]
public class MyClass:IMyClass
{
   public string myFunc(string url, ref string[] keys)
   {
      string retString = "";
      // do my stuff
      return retString;
   }
}

This class is registered by calling RegAsm.exe.

I tested this DLL in VB6 and it works okay.

Dim myClassInstance As MyClass
Set myClassInstance As New MyClass

Dim keys(0 to 1) As String
keys(0) = "a"
keys(1) = "b"

Dim url As String
url = "https://10.0.0.2"

Dim response As String
response = myClassInstance.myFunc(url, keys)

Now I need to use this DLL in Delphi 7 (I have no prior knowledge with Delphi).

I use Tlbimp to generate the required files. It looks like I can already reference the DLL in Delphi, but it is not working:

var
  myClassInstance : IMyClass;
  url : WideString
  keys : array[0..1] of WideString;
begin
    url := 'https://10.0.0.2';
    keys[0] := 'a';
    keys[1] := 'b';

    myClassInstance.MyFunc(url, keys); // Incompatible types error
end;

The function signature is (from Delphi 7 Editor):

function(const url: WideString; var keys: OleVariant): WideString;

How should I pass the correct parameters into this DLL in Delphi?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Ray Chang
  • 113
  • 1
  • 4

2 Answers2

1

At the COM level, the DLL is expecting you to pass in a VARIANT containing a SAFEARRAY of BSTR strings. VB and C# hide that detail from you using higher level syntaxes.

In Delphi, WideString is a wrapper for BSTR, and you can use the RTL's VarArrayCreate() function to create OLE/COM compatible arrays.

Try this:

var
  myClassInstance : IMyClass;
  url : WideString;
  keys : OleVariant;
begin
  url := 'https://10.0.0.2';
  keys := VarArrayCreate([0, 1], varOleStr);
  keys[0] := WideString('a');
  keys[1] := WideString('b');
  // don't forget to create the COM object instance
  // before trying to call any of its methods... 
  MyClassInstance := TMyClass.Create;
  myClassInstance.MyFunc(url, keys);
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for the prompt reply. The modified code can pass the compiler, however, I got this message in runtime: Project Project1.exe raised exception class EOleSysError with message '參數錯誤'. (The Chinese characters means "Parameter Error"). How can I locate the error? – Ray Chang May 24 '18 at 06:05
0

As you are using Delphi 7, string <> widestring.

Did you include the explicit casts to widestring as shown in Remy's example code?

  • Thanks. Yes I did the explicit casting. I think the problem is not the WideString but the array part. I tried to make a function with only one WideString as parameter it works find. – Ray Chang May 27 '18 at 06:11
  • What I got is those I commented under Remy's answer. (EOleSysError) – Ray Chang May 29 '18 at 09:45