Recent

Author Topic: use a Pascal dll with C#  (Read 876 times)

Hansvb

  • Sr. Member
  • ****
  • Posts: 349
use a Pascal dll with C#
« on: January 25, 2020, 08:34:30 pm »
Hi,

I made a verry small dll as a test to see how i can use a pascal dll with C#.
The dll is:


Code: Pascal  [Select]
  1. library TestDLL;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes
  7.   { you can add units after this };
  8.  
  9. function GetOne(): PChar; stdcall; export;
  10. begin
  11.   Result := 'One';
  12. end;
  13.  
  14. exports
  15.   GetOne;
  16.  
  17. begin
  18. end.
  19.  


The simple app in C# is:

Code: Pascal  [Select]
  1. [DllImport("TestDLL.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
  2.         public static extern string GetOne();
  3.  
  4.         private void button1_Click(object sender, EventArgs e)
  5.         {
  6.             try
  7.             {
  8.                 textBox1.Text = GetOne();
  9.             }
  10.             catch (Exception ex)
  11.             {
  12.                 string tmp = "Just to read the exception when debugging";
  13.             }
  14.         }

When i debug  i get first a strange message that the heap has been corrupted. When i continue the text "One" apears in the text box. This is not good. when i build and then execute the app crashes.
So i must do something wrong. Has anyone an idea how to create a dlle and use in in C#?
 

lainz

  • Hero Member
  • *****
  • Posts: 3474
    • Lainz
Re: use a Pascal dll with C#
« Reply #1 on: January 25, 2020, 08:40:55 pm »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7944
Re: use a Pascal dll with C#
« Reply #2 on: January 25, 2020, 09:14:06 pm »
C# pchar is more likely to be COM compatible PWIDECHAR in FPC/Delphi.


lainz

  • Hero Member
  • *****
  • Posts: 3474
    • Lainz
Re: use a Pascal dll with C#
« Reply #3 on: January 25, 2020, 09:24:01 pm »
Code: Pascal  [Select]
  1.  
  2. { String Utility }
  3.   function PWideCharToUTF8(const str: PWideChar): string;
  4.   begin
  5.     result := UTF8Encode(WideString(str));
  6.   end;
  7.  
  8. procedure SaveToFile(id: integer; filename: PWideChar); {$IFDEF windows}stdcall;{$ELSE}cdecl;{$ENDIF}
  9.   begin
  10.     BGRAPascalScript.bgra_SaveToFile(id, PWideCharToUTF8(filename));
  11.   end;

Is still needed to convert PWideChar like that, in the case we pass from C#?
« Last Edit: January 25, 2020, 09:31:24 pm by lainz »

jamie

  • Hero Member
  • *****
  • Posts: 2317
Re: use a Pascal dll with C#
« Reply #4 on: January 25, 2020, 10:22:39 pm »
Looks like a managed string issue...

Try returning something like  this..

In global heap of the DLL

Var
 SGlobableString :ShortString[255]; // just an example...

In your function …

 sGlobalestring :='One';
 Result := @sGlobaleString;

etc
Number 1 at blue screen app creations!

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7944
Re: use a Pascal dll with C#
« Reply #5 on: January 25, 2020, 10:55:41 pm »
Code: Pascal  [Select]
  1.  
  2. { String Utility }
  3.   function PWideCharToUTF8(const str: PWideChar): string;
  4.   begin
  5.     result := UTF8Encode(WideString(str));
  6.   end;
  7.  

This code is wrong, it should probably return "widestring". Keep in mind that any "string" in  .NET means  "widestring" in FPC/Delphi. Similarly a char* then becomes pwidechar.

lainz

  • Hero Member
  • *****
  • Posts: 3474
    • Lainz
Re: use a Pascal dll with C#
« Reply #6 on: January 26, 2020, 12:22:42 am »
Cool thanks. That code was strangely working then but now I think also utf8encode is not needed since it was like a trick in older fpc.

Maybe now works also without the cast?

Hansvb

  • Sr. Member
  • ****
  • Posts: 349
Re: use a Pascal dll with C#
« Reply #7 on: January 26, 2020, 10:18:52 am »
I can't get it to to work... passing a string from a Pascal dll to C#.  So i tried to pass an integer. That works fine.  It must be possible to pass a (Wide)string.


Thaddy

  • Hero Member
  • *****
  • Posts: 9646
Re: use a Pascal dll with C#
« Reply #8 on: January 26, 2020, 11:55:25 am »
I can't get it to to work... passing a string from a Pascal dll to C#.  So i tried to pass an integer. That works fine.  It must be possible to pass a (Wide)string.
C# doesn't know Pascal native string types at all. You need PWideChar to get it working reliably.
I am more like donkey than shrek

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7944
Re: use a Pascal dll with C#
« Reply #9 on: January 26, 2020, 02:07:27 pm »
Afaik widestring is compatible to BStr in C# interop code.

But maybe returning strings is not supported. Try with an out parameter first.

Also you might need to initialize COM (coinitialize in comobj or so)