0

I tried to call a dll that is coded in delphi in C#. (delphi 11 64bit) I believe there will be some problems. Therefore, I tried some example in these website: Calling a Delphi method in a dll from c# Calling a Delphi DLL from a C# .NET application

But there is no response, and the applicaiton closes.

These are my codes:

example 1

delphi

function DBConnect1(inputStr,connStr:PWideChar):PWideChar;stdcall;
begin
  try
     result:=PWideChar('Hello from Delphi!');
  except
     result:=PWideChar('Exception');
  end;
end;

C#

[DllImport("Project1.dll",
    CallingConvention = CallingConvention.StdCall,
    CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string DBConnect1(string inputString, string connectionString);

string inputString = "Parker";
string connectionString = "MyComputer";
string dbStrObj1 = DBConnect1(inputString, connectionString);
MessageBox.Show(dbStrObj1);

example 2

delphi

function Test1(sFD,sVD,sINI,sCh,sSD: string): PWideChar;stdcall;
var
  tempStr:string;
  str:WideString;
begin
  tempStr:=sFD+sVD+sINI+sCh+sSD;
  try
   result:= PWideChar(tempStr);
  except
    str:='Error';
    result:=PWideChar(str);
  end;
    result:=PWideChar(str);
end;

C#

[DllImport("Project1.dll", EntryPoint = "LoginLic", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string LoginLic(string s1, string s2, string s3, string s4, string s5);

string strId = "PCMS";
string strVersion = "AD19";
string strIni = @"";
string strCheck = "0";
string strSubDate = null;
string aa;
aa = UseDll.LoginLic(strId, strVersion, strIni, strCheck, strSubDate);
  • 1
    second one has mismatched function names. For the first one, no error message from C# runtime at all? Make sure you are matching 32/64 bit – pm100 Jan 13 '23 at 02:20
  • note that sample explicitly says not to use string as a return type – pm100 Jan 13 '23 at 02:22
  • Hi, pm100. Thanks a lot for your response. First of all, I changed the platform targer to 64 bit in Build page. And solution platform is Any CPU. There is no response and no error message. Even, I used try-catch that still no response and the application closes. Second, I changed solution platform to x64 and Platform target is x64. The error is DllNotFoundException. And sorry about that, I didn't change the name in this page. The name is LoginLic. –  Parker Shiung Jan 13 '23 at 02:51
  • did you read my second comment tho – pm100 Jan 13 '23 at 04:33
  • 1
    another suggestion, write a very simple function, say one that returns 42, get tha going and gradually add more argument and return types – pm100 Jan 13 '23 at 04:38
  • Hi, pm100, I still need a return valut that is string. I would use this string to do something. Therefore, the string is essential. –  Parker Shiung Jan 13 '23 at 07:41
  • I didn't understand your another suggestion. Would you explain it more details? –  Parker Shiung Jan 13 '23 at 07:44
  • Hi pm100. I tried a example today.https://stackoverflow.com/questions/53529623/passing-string-from-delphi-to-c-sharp-returns-null-however-it-works-fine-when-i It worked. –  Parker Shiung Jan 16 '23 at 09:45

1 Answers1

0

You have to marshall function parameters also. Refer this link for passing string with Marshalling https://learn.microsoft.com/en-us/dotnet/framework/interop/default-marshalling-for-strings

[DllImport("Project1.dll",CallingConvention = CallingConvention.StdCall,CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static extern string DBConnect1(MarshalAs(UnmanagedType.LPWStr)]string inputString, MarshalAs(UnmanagedType.LPWStr)] string connectionString);
Hari E
  • 526
  • 2
  • 14
  • Hi Hari, thanks a lot for your reply. I tried your suggestion and edit my code. But there is still no response. –  Parker Shiung Jan 13 '23 at 02:58
  • You can try with BSTR. Both in delphi and C# input strings. I used to interop between C++ and C# with BSTR strings – Hari E Jan 13 '23 at 03:09
  • Try to debug your code with native debugger. To enable native debugging Properties -> Debug -> Enable the check box "Enable Native Debugging' option – Hari E Jan 13 '23 at 03:12
  • Hari, I tried your suggestion that is 'enable native debuggin'. I got a exception thrown which is my.exe has triggered a breakpoint. And got a exception unhandled that detail is Unhandled exception at 0x00007FFC961AF609 (ntdll.dll) in my.exe: 0xC0000374: parameters: 0x00007FFC962197F0 –  Parker Shiung Jan 13 '23 at 03:49
  • BTW, I call the dll and use that function to send the string to the server. That was a success. The server received the string I sent. But it still has the exception unhandled problem in C#. –  Parker Shiung Jan 13 '23 at 04:05
  • Can you please specify the exception – Hari E Jan 13 '23 at 05:03
  • Hari, since this is Chinese, it took me a while to understand how to explain it in English. This means "the stack around the variable is corrupted". –  Parker Shiung Jan 13 '23 at 05:40
  • Then Change the calling convention to Cdel `CallingConvention = CallingConvention.Cdecl` and cdel in Delphi – Hari E Jan 13 '23 at 05:45
  • Still can't. Getting the same issue... –  Parker Shiung Jan 13 '23 at 06:17
  • Are you using BSTR strings or others ? – Hari E Jan 13 '23 at 06:18
  • In Delphi, I tried input and return with 'widestring'. I tried UnmanagedType.BStr in C#, and I got AccessViolationException. And I removed UnmanagedType.BStr, still get the samce exception: AccessViolationException. –  Parker Shiung Jan 13 '23 at 07:38
  • try with integer or double values, if it works there is problem only on String Marshaling – Hari E Jan 13 '23 at 07:43
  • Add new Method with single integer input and return the same input and try to print it on C# exe console – Hari E Jan 13 '23 at 07:44
  • Hi, Hari, I tried integer and double, that all work well and get the correct value. I tried it on winform, and show the value on the messagebox. Only string make me very confused. I tried your suggestion debugging code in enable native debugging mode. It could get the value I want but doesn't work without native debugging mode. –  Parker Shiung Jan 13 '23 at 07:48
  • Somehow you are marshaling string in wrong way that why you are getting Exception. – Hari E Jan 13 '23 at 07:52
  • Can you share your delphi method here ? – Hari E Jan 13 '23 at 07:53
  • Hi Harry. May I have your personal contact information? I could post the screenshot to you. –  Parker Shiung Jan 13 '23 at 08:01
  • Here is a simple function in delphi: function Getname(str1,str2,str3:string): PWideChar;stdcall ; var total:string; begin total:= 'str1:'+str1+',str2:'+str2+',str3:'+str3; result:=PWideChar('12348;asder'); showmessage(total); end; –  Parker Shiung Jan 13 '23 at 08:01
  • Here is a code in C#: [DllImport("Project1.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] [return:MarshalAs(UnmanagedType.LPWStr)] public static extern string Getname( [MarshalAs(UnmanagedType.LPWStr)] string str1, [MarshalAs(UnmanagedType.LPWStr)] string str2, [MarshalAs(UnmanagedType.LPWStr)] string str3); –  Parker Shiung Jan 13 '23 at 08:04
  • Hi, Hari I tried a example today.https://stackoverflow.com/questions/53529623/passing-string-from-delphi-to-c-sharp-returns-null-however-it-works-fine-when-i I would use this example to understand how to work. –  Parker Shiung Jan 16 '23 at 09:44