Recent

Author Topic: Using C# DLL in Lazarus  (Read 7379 times)

JohnRambo

  • Newbie
  • Posts: 4
Using C# DLL in Lazarus
« on: September 20, 2017, 08:16:49 pm »
At first I admit that in C # I am green like chives. I want to prepare a C# DLL using the UnmanagedExports tool (https://www.nuget.org/packages/UnmanagedExports) in the C # DLL. Here's an example by author:https://stackoverflow.com/a/2055508/1919267 .
So far ok, managed to produce a DLL and use it in Delphi. But there is a problem: when I want to use the same file in Lazarus, it returns nothing. The code:
Code: Pascal  [Select][+][-]
  1. var
  2.   adder : IDotNetAdder;
  3. begin
  4.   try
  5.    CreateDotNetAdder(adder);
  6.    Writeln('4 + 3 = ', adder.Add3(4));
  returns me 0 (so I am thinking that DLL response  is nil). Is there any solution to fix that? Should I need to fix my pascal code or fix that DLL?

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Using C# DLL in Lazarus
« Reply #1 on: September 21, 2017, 11:11:38 am »
Next time you cross post I will hold my comments...  >:(
Please do not cross post in the future.  ;D
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

tudi_x

  • Hero Member
  • *****
  • Posts: 532
Re: Using C# DLL in Lazarus
« Reply #2 on: September 21, 2017, 11:30:25 am »
@avra - the deletion of posts does not seem to work. maybe he opened a new one due to code not inserted as recommended in the first place.

@rambo - i think you need to have a handler for the dll and define the external function, something like
Code: Pascal  [Select][+][-]
  1. TGetDeviceInfo = function(AIndex: integer): PTDeviceInfoRecord; cdecl;

after you define the handler and the function you can use it.
Lazarus 2.0.2 64b on Debian LXDE 10

JohnRambo

  • Newbie
  • Posts: 4
Re: Using C# DLL in Lazarus
« Reply #3 on: September 21, 2017, 03:30:21 pm »
Sorry for double topic but I can't delete topic in wrong category. I cant use COM, because I need to use old version of Lazarus (without ActiveX).
In my code I declare procedure in static way:
Code: Pascal  [Select][+][-]
  1. var
  2.   Form1: TForm1;
  3.  procedure createdotnetadder(out instance:IDotNetAdder); stdcall external 'DelphiNETstd.dll' name 'createdotnetadder';
  4. implementation
  5. { TForm1 }
When I try to do it dynammicaly nothing work, only more problems. I don't understand that Delphi do it perfectly, but Lazarus not. In attachments I put .dll file and my pas unit. I don't asking about do it for me but to show me the way

JohnRambo

  • Newbie
  • Posts: 4
Re: Using C# DLL in Lazarus
« Reply #4 on: September 21, 2017, 04:53:56 pm »
OK I made it. :D
Firstly we need to get some information: https://stackoverflow.com/a/9353800
"In C#/C++ you will need to define the Result as out Parameter, in order to maintain binary code compatibility of stdcall calling conventions" - thats the key. In my C# code I was use return. For Delphi its ok, but for Lazarus it is problematic. So I retyped my c# code from:
Code: C#  [Select][+][-]
  1.    [ComVisible(true)]
  2.     [ClassInterface(ClassInterfaceType.None)]
  3.     public class DotNetAdder : DelphiNET.IDotNetAdder
  4.     {
  5.         public void Add3(int left)
  6.         {
  7.             return= left + 3;
  8.            
  9.         }
  10.     }

to
Code: C#  [Select][+][-]
  1.    [ComVisible(true)]
  2.     [ClassInterface(ClassInterfaceType.None)]
  3.     public class DotNetAdder : DelphiNET.IDotNetAdder
  4.     {
  5.         public void Add3(int left,out int result)
  6.         {
  7.             result= left + 3;
  8.            
  9.         }
  10.     }
And change my pascal code from:
Code: Pascal  [Select][+][-]
  1. //interface:
  2.   type
  3.   IDotNetAdder = interface
  4.   ['{ACEEED92-1A35-43fd-8FD8-9BA0F2D7AC31}']
  5.     function Add3(left : integer):integer; stdcall;
  6.   end;
  7.  
  8. //execution:
  9. var
  10.   adder : IDotNetAdder;
  11. begin
  12.   try
  13.    CreateDotNetAdder(adder);
  14.    Writeln('4 + 3 = ', adder.Add3(4));

to
Code: Pascal  [Select][+][-]
  1.  
  2. //interface:
  3.   type
  4.   IDotNetAdder = interface
  5.   ['{ACEEED92-1A35-43fd-8FD8-9BA0F2D7AC31}']
  6.     function Add3(left : integer;out result:integer); stdcall;
  7.   end;
  8.  
  9. //execution:
  10.  CreateDotNetAdder(adder);
  11.    i:=4;
  12.    finally
  13.    adder.Add3(i,x);
  14.   showmessage('4 + 3 = '+ (inttostr(x)));
  15.  

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Using C# DLL in Lazarus
« Reply #5 on: September 21, 2017, 05:01:54 pm »
Code: Pascal  [Select][+][-]
  1. void Add3(int left)

translates to

Code: Pascal  [Select][+][-]
  1. procedure Add3(left:integer)

If you want result from your subroutine, you need to change C# code to

Code: Pascal  [Select][+][-]
  1. int Add3(int left)

and Pascal version to

Code: Pascal  [Select][+][-]
  1. function Add3(left:integer) : integer

 

TinyPortal © 2005-2018