2
$\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$
4
  • $\begingroup$ Find out what calling convention Delphi uses and set the CallingConvention option of DefineDLLFunction appropriately. $\endgroup$
    – Szabolcs
    Jan 15, 2017 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, 2017 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, 2017 at 13:14
  • $\begingroup$ is this question supposed to be in stckoverflow instead? $\endgroup$
    – justyy
    Jan 26, 2017 at 16:25

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.