1
$\begingroup$

I'm trying to call a function from a 32-bit DLL created in Delphi. My (simplified) function is defined in Delphi like so:

library my;

type TArrayOfReal = array of Real;

function sumarrayreal(x,y : Real) : TArrayOfReal;
begin
  SetLength(Result,3);
  Result[0]:=x;
  Result[1]:=y;
  Result[2]:=x+y;
end;

exports sumarrayreal;

I'm using a special type TArrayOfReal here because Delphi functions (as far as I know) can't return arrays, not even static ones.

Then I call my DLL from a 64-bit version of Mathematica 11:

(*In*)
Needs["NETLink`"]

UninstallNET[]
InstallNET["Force32Bit" -> True]

fun1 = DefineDLLFunction["sumarrayreal", 
  "my.dll", 
  "double[]", {"double", "double"}]

(*Out*)
Function[Null, 
 If[NETLink`DLL`Private`checkArgCount["sumarrayreal", {##1}, 2], 
  Wolfram`NETLink`DynamicDLLNamespace`DLLWrapper2`sumarrayreal[##1], 
$Failed], {HoldAll}]

When I try to use this function

(*In*)
fun1[2., 3.]

(*Out*)
$Failed 

I receive an error:

A .NET exception occurred: "System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'return value': Invalid managed/unmanaged type combination.

Even a function that returns a string

(*delphi code*)
function sumarray(x,y : Real) : string;
begin
  Result := FloatToStr(x)+' '+FloatToStr(y) + ' '+ FloatToStr(x+y)
end;

(*Mathematica In*)
fun2 = DefineDLLFunction["sumarray", 
  "my.dll", 
  "string", {"double", "double"}] 

doesn't work:

A .NET exception occurred: "System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

But a function that returns a single value DOES work:

(*delphi code*)
function sum(x,y : Real) : Real;
begin
  Result := x+y;
end;

(*In*)
fun3 = DefineDLLFunction["sum", 
  "my.dll", 
  "double", {"double", "double"}]   

 (*Out*)
Function[Null, 
 If[NETLink`DLL`Private`checkArgCount["sum", {##1}, 2], 
  Wolfram`NETLink`DynamicDLLNamespace`DLLWrapper1`sum[##1], $Failed], 
{HoldAll}]

(*In*)
fun3[2., 3.]

(*Out*)
5.

The problem is that I absolutely need to return an array (or a string at worst), not a single value! What do I do with that? Thank you.

$\endgroup$
  • $\begingroup$ Find out what calling convention Delphi uses and set the CallingConvention option of DefineDLLFunction appropriately. $\endgroup$ – Szabolcs Jan 15 '17 at 17:04
  • $\begingroup$ @Szabolcs AFAIK Deplhi uses "StdCall". I tried this as CallingConvention option, and "CDecl", and "ThisCall", and Automatic. Still doesn't work. $\endgroup$ – floyd17 Jan 15 '17 at 17:13
  • 1
    $\begingroup$ Perhaps you will have better luck if you ask on StackOverflow about how to call a Delphi DLL from C# (leave the Mathematica part out). Unfortunately I am not very familiar with this technology. $\endgroup$ – Szabolcs Jan 16 '17 at 13:14
  • $\begingroup$ is this question supposed to be in stckoverflow instead? $\endgroup$ – justyy Jan 26 '17 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.