Recent

Author Topic: [SOLVED]Dll pascal Library to be used also with .net  (Read 7358 times)

amartitegui

  • Jr. Member
  • **
  • Posts: 84
[SOLVED]Dll pascal Library to be used also with .net
« on: February 23, 2018, 04:21:10 pm »
I got a little problem trying to build a dll that can be used from .net
I has to do with structures / record.
Anybody knows of a right way to use structure and record to pass to a dll (dll lazarus)?
Pointers dont work very well... or I dont get them right.
Passing a pointer to structure using mashal:
(NewFaborderis a structure like this)
 Public Structure FabOrder     
        Public NumOrder As Int32
        Public Material As Int32
        Public Numero As Int32
    End Structure

 BufPtr = Marshal.AllocHGlobal(Marshal.SizeOf(NewFaborder))
 Marshal.StructureToPtr(NewFaborder, BufPtr, False)

 <System.Runtime.InteropServices.DllImport("PRint_partes_dll.dll", charset:=CharSet.Auto, EntryPoint:="ReceiveOrderAndShowNumOrder", CallingConvention:=CallingConvention.StdCall)> _
    Private Shared Function ReceiveOrderAndShowNumOrder(ByRef ptr As FabOrder) As FabOrder
    End Function

Also tried:
 Private Shared Function ReceiveOrderAndShowNumOrder(ByRef ptr As int64) As int64
    End Function


and using it at dll function:
Function ReceiveOrderAndShowNumOrder(Stringer:PFaborder):PFaborder;stdcall;
begin
  Result:=Stringer;
end;               
Being:
PFaborder=^TFabOrder;
and
TFabOrder=record
   NumOrder:int32;
   Material:int32;
   Numero:int32;
 end;     
SHould return same NEWFABORDER.
but even it does not give any error or exception, data is not correct.

I got Main doubt: What kind of data shoud I use to send Pointer to the dll????
Private Shared Function ReceiveOrderAndShowNumOrder(??????) As ??????

IntPtr is what I see I can get with vb.net but....
thanks
« Last Edit: February 27, 2018, 07:51:24 am by amartitegui »

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Dll pascal Library to be used also with .net
« Reply #1 on: February 23, 2018, 09:41:53 pm »
I got Main doubt: What kind of data shoud I use to send Pointer to the dll????
Private Shared Function ReceiveOrderAndShowNumOrder(??????) As ??????

IntPtr is what I see I can get with vb.net but....

Search for examples, eg:

https://stackoverflow.com/questions/47921321/pass-struct-from-c-sharp-to-c-dll

In that example, ignore the stuff about arrays since you don't have any arrays in your structure.

Are you calling a 64-bit dynamic library? Make sure you compile your VB.NET code with /platform:x64 so that IntPtr is 8 bytes.

More on dynamic libraries here, although no examples of structures:

https://macpgmr.github.io

amartitegui

  • Jr. Member
  • **
  • Posts: 84
Re: Dll pascal Library to be used also with .net
« Reply #2 on: February 23, 2018, 11:03:08 pm »
Thanks man, ill take a look at that info.
Btw, both lazarus testing dll and .net compiled x86.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Dll pascal Library to be used also with .net
« Reply #3 on: February 23, 2018, 11:12:02 pm »
More info also here.

guest60499

  • Guest
Re: Dll pascal Library to be used also with .net
« Reply #4 on: February 24, 2018, 05:22:20 pm »
If you only need to support Windows, you may want to make a COM component. I am not sure if anyone has successfully done so with FPC. Doing so will better integrate with C#; doing this any other way will likely cause you to need to generate a wrapper class in C#. It is my understanding that the .NET runtime will autogenerate COM wrapper classes.

Not to derail the thread, but if anyone has any information about creating or using COM objects contributing to the Wiki would be very helpful.

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Dll pascal Library to be used also with .net
« Reply #5 on: February 24, 2018, 05:53:00 pm »
Doing so will better integrate with C#; doing this any other way will likely cause you to need to generate a wrapper class in C#. It is my understanding that the .NET runtime will autogenerate COM wrapper classes.

You would use something like TlbImp.exe from the .NET SDK to create an interop assembly (.dll) for your COM component (or application that supports COM Automation). This assembly can then be used by any .NET code to access your component or app.

However, you can create your own interop assembly for a native dynamic library. This assembly will be usable on all platforms, not just Windows. More here under "Pascal Dynamic Libraries":

https://macpgmr.github.io

Not to derail the thread, but if anyone has any information about creating or using COM objects contributing to the Wiki would be very helpful.

Using COM is described in wiki:

http://wiki.freepascal.org/Office_Automation

The Mac equivalent is under "Mac Automation with Pascal" here:

https://macpgmr.github.io/ObjP/MacAutomationWithPascal.html

guest60499

  • Guest
Re: Dll pascal Library to be used also with .net
« Reply #6 on: February 24, 2018, 07:55:20 pm »
However, you can create your own interop assembly for a native dynamic library. This assembly will be usable on all platforms, not just Windows. More here under "Pascal Dynamic Libraries":

https://macpgmr.github.io
Is there more explanation available elsewhere? I do see that this uses C# via Mono, which makes sense. But I don't see how this uses something like COM, whose Linux equivalent is roughly GObject.

Using COM is described in wiki:

http://wiki.freepascal.org/Office_Automation

The Mac equivalent is under "Mac Automation with Pascal" here:

https://macpgmr.github.io/ObjP/MacAutomationWithPascal.html
This is true, but I was never able to generalize it to non-Office automation. It may have been my choice of COM control; Microsoft's RDP client may be broken. However, I am still not sure what the proper invocations are to create and use a COM object. I don't have any background using COM with C++ or creating COM objects with the Microsoft tools.

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Dll pascal Library to be used also with .net
« Reply #7 on: February 24, 2018, 08:16:02 pm »
https://macpgmr.github.io
Is there more explanation available elsewhere? I do see that this uses C# via Mono, which makes sense. But I don't see how this uses something like COM, whose Linux equivalent is roughly GObject.
[/quote]

Right, nothing to do with COM. But the benefits of writing the interop's wrapper yourself means you get cross-platform.

This is true, but I was never able to generalize it to non-Office automation. It may have been my choice of COM control; Microsoft's RDP client may be broken. However, I am still not sure what the proper invocations are to create and use a COM object. I don't have any background using COM with C++ or creating COM objects with the Microsoft tools.

In Delphi, you could add COM Automation support to any app for about the last 20 years. See Delphi's TAutoObject class. Don't know about FPC. Worked perfectly in Delphi.

Again, though, you get much better performance calling a native dynamic library yourself rather than invoking it via COM.

amartitegui

  • Jr. Member
  • **
  • Posts: 84
Re: Dll pascal Library to be used also with .net
« Reply #8 on: February 26, 2018, 04:49:50 pm »
Ufff.
I'm not really sure why.
But there is some kind of trick about Adresses.
Trying whatever I do, pointers are not right.... see this simple test.
in vb.net (copile I386)
First:
 <System.Runtime.InteropServices.DllImport("PRint_partes_dll.dll", charset:=CharSet.Auto, EntryPoint:="ReceiveOrderAndShowNumOrder", CallingConvention:=CallingConvention.StdCall)> _
    Private Shared Function ReceiveOrderAndShowNumOrder(ByRef ptr As IntPtr) As IntPtr

    End Function
And later onclick button

Dim Integertu As Integer = 23
Dim Handle As GCHandle = GCHandle.Alloc(Integertu)
Dim ptr As IntPtr = GCHandle.op_Explicit(Handle)
Dim returning As IntPtr = ReceiveOrderAndShowNumOrder(ptr)


and lazarus Dll. The function just gives back the value:

Function ReceiveOrderAndShowNumOrder(Stringer:intptr):intptr;stdcall;
begin
   Result:=Stringer;
end;         


I get when debugging different values
VB.net: ptr  different than returning
SHould it be same shouldn't it?


ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Dll pascal Library to be used also with .net
« Reply #9 on: February 26, 2018, 07:14:31 pm »
Dll:
Code: Pascal  [Select][+][-]
  1. library ProjectDll;
  2. {$mode objfpc}{$H+}
  3.  
  4. uses
  5.   Classes;
  6.  
  7. type
  8.   TTestRec = record
  9.     Field1: Int32;
  10.     Field2: Int64;
  11.   end;
  12.  
  13. procedure FillRec(var Rec: TTestRec); stdcall;
  14. begin
  15.   Rec.Field1 := 11;
  16.   Rec.Field2 := 22;
  17. end;
  18.  
  19. exports FillRec;
  20.  
  21. begin
  22. end.

Test on Lazarus:
Code: Pascal  [Select][+][-]
  1. program ProjectUse;
  2. {$APPTYPE CONSOLE}
  3. {$MODE OBJFPC}
  4.  
  5. type
  6.   TTestRec = record
  7.     Field1: Int32;
  8.     Field2: Int64;
  9.   end;
  10.  
  11. procedure FillRec(var Rec: TTestRec); stdcall; external 'ProjectDll.dll';
  12.  
  13. var
  14.   R: TTestRec;
  15. begin
  16.   FillRec(R);
  17.   Writeln('Field1=', R.Field1, ' Field2=', R.Field2);
  18.   Readln;
  19. end.

Test on VB:
Code: Visual Basic  [Select][+][-]
  1. Module Module1
  2.  
  3.     Structure TTestRec
  4.         Public Field1 As Int32
  5.         Public Field2 As Int64
  6.     End Structure
  7.  
  8.     <System.Runtime.InteropServices.DllImport("ProjectDll.dll")>
  9.     Private Sub FillRec(ByRef Rec As TTestRec)
  10.  
  11.     End Sub
  12.  
  13.     Sub Main()
  14.         Dim R As TTestRec
  15.         FillRec(R)
  16.         Console.WriteLine("Field1={0}, Field2={1}", R.Field1, R.Field2)
  17.         Console.ReadLine()
  18.     End Sub
  19.  
  20. End Module

All work.

amartitegui

  • Jr. Member
  • **
  • Posts: 84
Re: Dll pascal Library to be used also with .net
« Reply #10 on: February 26, 2018, 07:26:52 pm »
Dude , gonna check rigth away.

amartitegui

  • Jr. Member
  • **
  • Posts: 84
Re: Dll pascal Library to be used also with .net
« Reply #11 on: February 26, 2018, 07:54:38 pm »
What version of vb.net u using?
Code: Diff  [Select][+][-]
  1. Imports System.Runtime.InteropServices
  2. Imports System
  3. Module testmodule
  4.     Structure FabOrder
  5.         Public NumOrder As Int32
  6.         Public Material As Int32
  7.         Public Numero As Int32
  8.     End Structure
  9.  
  10.     <System.Runtime.InteropServices.DllImport("PRint_partes_dll.dll", charset:=CharSet.Auto, EntryPoint:="GetNumId")> _
  11.     Public Sub FillRec(ByRef Rec As FabOrder)
  12.     End Sub
  13.  
  14.  
  15. End Module

Code: Diff  [Select][+][-]
  1.  Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
  2.         Dim nuevo_numorder As FabOrder
  3.         FillRec(nuevo_numorder)
  4.     End Sub

Laz DLL:
Code: Pascal  [Select][+][-]
  1. library PRint_partes_dll;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes,sysutils;
  7. type
  8.   TFabOrder=record
  9.    NumOrder:int32;
  10.    Material:int32;
  11.    Numero:int32;
  12.  end;
  13.  PFaborder=^TFabOrder;
  14. var
  15.   Ptr:PFaborder;
  16. Function GetNumId(NumId:WideString):Int64;Stdcall;
  17. begin
  18.   Result:=0;
  19.   if NumId='MIERDA' then begin
  20.   Result:=1;
  21.  
  22.   end;
  23. end;
  24. procedure FillRec(var Rec: TFabOrder); stdcall;
  25. begin
  26.   Rec.NumOrder := 11;
  27.   Rec.Material := 22;
  28.   rec.Numero:=34
  29. end;
  30. Function ReceiveOrderAndShowNumOrder(Stringer:int32):int32;stdcall;
  31. begin
  32.   Result:=Stringer;
  33. end;
  34. Exports GetNumId;
  35. Exports ReceiveOrderAndShowNumOrder;
  36. exports FillRec;
  37. begin
  38. end.      

I get:
Excepción no controlada del tipo 'System.AccessViolationException' en PruebaDllPascal.exe
Información adicional: Intento de leer o escribir en la memoria protegida. A menudo, esto indica que hay otra memoria dañada.
Have u tryied with VB.net or  VB6 ?
thanks for your help though

amartitegui

  • Jr. Member
  • **
  • Posts: 84
Re: Dll pascal Library to be used also with .net
« Reply #12 on: February 26, 2018, 08:00:08 pm »
Ah, also made a change turning from private to public the button_click event. And even further, i made a sub main in the module and call it.
same result.
System.AccessViolationException
 %)

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Dll pascal Library to be used also with .net
« Reply #13 on: February 26, 2018, 09:13:33 pm »
Ah, also made a change turning from private to public the button_click event. And even further, i made a sub main in the module and call it.
same result.
System.AccessViolationException
 %)
...EntryPoint:="GetNumId", but Public Sub FillRec(ByRef Rec As FabOrder)

amartitegui

  • Jr. Member
  • **
  • Posts: 84
Re: Dll pascal Library to be used also with .net
« Reply #14 on: February 26, 2018, 11:02:19 pm »
Shit youre right.
Treacherous ctrl-v
Thanks pal

 

TinyPortal © 2005-2018