I have a problem.
I can pass 2D array from Delphi to C++ DLL that created by CodeBlocks.
My function in C++ DLL is :
double __declspec(dllexport) __cdecl mainFunction(double** arr, int64 length)
And my Function In Delphi to call DLL is :
type
DynMatrixDouble = array of array of double;
.
.
function arr(X:DynMatrixDouble; Y: integer):double; stdcall; external 'Array_dll.dll' name 'mainFunction';
This code works well and the values of the variables are transferred between the program and the dll.But when I convert a function that has a 2D array in input in Matlab to DLL or /to C++ to make DLL with CodeBlocks, It's no longer like the code above, this is :
double calc_det(int64m_T n, const emxArray_real_T *arr)
It seems I should make 2D Double array Variable In "emxArray_real_T" Type in Delphi and pass to DLL.
I searched and reached the link below:
How to convert float[][] type array to "emxArray_real_T *x"
But I couldn't find the answer to my question.My question is how can define "emxArray_real_T" type in Delphi for 2D Array and send it to dll ?
Can anyone help me how to do it right?
Thanks.
Related
I know that a similar question has already been posted, but its solution doesn't work for me. In my spec file I have the code:
type Colour_Component is mod 256;
type Colour is
record
A, R, G, B : Colour_Component;
end record;
type Raw_Image_Data is array (Interfaces.C.int range <>) of Colour;
type Raw_Image is access all Raw_Image_Data;
pragma Convention (C, Raw_Image);
Then I try to interface with a C function:
function C_SDL_CreateRGBSurfaceFrom (
Pixels : Raw_Image;
Width : int;
Height : int;
Depth : int;
Pitch : int;
Rmask : Unsigned_32;
Gmask : Unsigned_32;
Bmask : Unsigned_32;
Amask : Unsigned_32)
return System.Address;
pragma Import (C, C_SDL_CreateRGBSurfaceFrom, "SDL_CreateRGBSurfaceFrom");
But when I try to compile it I get a warning:
warning: type of "C_SDL_CreateRGBSurfaceFrom.Pixels" does not correspond to C pointer
warning: this access type does not correspond to C pointer
Since I have my compiler flags set to treat warnings as errors this doesn't compile. Any advice on how to fix this?
Ada arrays come in two flavours, constrained and unconstrained arrays. C arrays are constrained (newer C standards also have dynamically sized arrays), but if you pass C arrays around function calls you either terminate them with a zero element or with a separate length parameter.
Anyway, you declared your parameter Raw_Image as an unconstrained array. There is no counterpart in C. You can only pass constrained arrays from or to C.
I think you have two options: (1) use address to access conversion or (2) use the binding generator -fdump-ada-spec
(1) declare your first parameter as of type System.Address and use the package System.Address_To_Access_Conversions
(2) The easiest way is to use the gcc switch -fdump-ada-spec on a C header. See Generating Ada Bindings for C and C++ headers
I have a C API with
void Fill(size_t * val){
*val = 15;
}
How can I call this method from Swift 3 and fill the internal class variable var number? Also, what type should it have?
If you open the C header file in Xcode and select "Navigate->Jump to Generated Interface" from the Xcode menu then you'll see that the
function is imported to Swift as
public func Fill(_ val: UnsafeMutablePointer<Int>!)
You call it from Swift by passing the address of an initialized
variable with & as inout expression, compare "Interacting with C APIs":
Mutable Pointers
When a function is declared as taking an UnsafeMutablePointer<Type>
argument, it can accept any of the following:
...
An in-out expression that contains a mutable variable, property, or subscript reference of type Type, which is passed as a pointer to the address of the mutable value.
...
In your case:
var myval = 0 // Type is `Int`
Fill(&myval)
But Swift defines size_t as well as
public typealias size_t = Int
therefore you can (even better) define the variable as
var myval: size_t = 0
which would then also compile on other platforms which might define
size_t differently.
First, you'll need to find what is the actual primitive type of size_t on your platform. Then, you can use this table to find out what you'll need to use as this function's type. For instance, supposing size_t is a #define alias for unsigned long, the Swift signature for this function will be:
func Fill(_ val: UnsafeMutablePointer<CUnsignedLong>!)
Since Objective-C is a strict superset of C, you can add C files to your project the same way you would add Objective-C files: Create a bridging header and import the functions you want to use in it.
Once you've created a bridging header and imported the appropriate header file, you should be able to call Fill from Swift code with no issue. You should be able to use it as follows:
import Foundation
class SomeClass {
var number: CUnsignedLong = 0
func someMethod() {
Fill(&number)
}
}
I'm using Delphi to load a dll (that I created in Delphi XE-3) for the purposes of interfacing with some C code. My problem is figuring out why my arrays aren't being passed to the c functions - they're the only ones not to. The delphi file (simplified) looks like this:
program CallcCode
uses
SysUtils, Windows,
DLLUnit in 'DLLUnit.pas'; // Header conversion
var
DLLHandle: cardinal;
n: Integer;
A: TArray<Integer>;
result1: Integer;
begin
// Initialize each Array
SetLength(A,n);
A[0] = ...;
// Load the DLL (and confirm its loaded)
DLLhandle := LoadLibrary('dllname.dll');
if DLLhandle <> 0 then
begin
result1 := dll_func1(n,A); // A and B are not passed correctly
end
FreeLibrary(DLLHandle);
end.
I successfully "Trace into" dll_func1 the first time, entering DLLUnit, which has:
const
nameofDLL = 'dllname';
function dll_func1(n: Integer; A: TArray<Integer>): Integer; cdecl; external nameofDLL;
"Tracing-into" again, I arrive at the c file, which still has the correct n and DLLdefs values, but A (under the "Local Variables" heading) has become:
[-] A :(Aplha-Numeric)
..[0] 0 (0x00000000)
I know that I'm at least accessing the DLL (hopefully) correctly because other function calls work as they should and I am able to trace into the dll_func1.c file without a problem. I tried changing the function to
function dll_func1(n: Integer; A: PInteger): Integer; cdecl; external nameofDLL;
...
result1 := dll_func1(n,PInteger(A))
or
function dll_func1(n: Integer; A: PInteger): Integer; cdecl; external nameofDLL;
...
result1 := dll_func1(n,#A[0])
(using both TArray and array of Integer or A) but there is no change, which leaves me to believe this is related to a problem I'm not seeing. The whole thing compiles and runs, but result1 is incorrect because of the TArray failures. Any ideas on what is going wrong?
EDIT The function in C as:
int dll_func1(int n, int A [])
Your question contains two Delphi declarations for the external function. One of them uses TArray<T> as a parameter. That is completely wrong. Don't do that. You cannot use a Delphi dynamic array as an interop type. The reason being that TArray<T> is a complex managed type that can only be created and consumed by Delphi code.
You need to do as I do below, and as I explained in my answer to your previous question, and declare the array parameter as pointer to element type. For example, PInteger, PDouble, etc.
There's quite a lot of confusion here, and needless complexity. What you need is the simplest possible example that shows how to pass an array from your Delphi code to C code.
Here is is.
C code
//testarray.c
void printDouble(double d); // linker will resolve this from the Delphi code
void test(double *arr, int count)
{
int i;
for (i=0; i<count; i++)
{
printDouble(arr[i]);
}
}
Delphi code
program DelphiToC;
{$APPTYPE CONSOLE}
uses
Crtl;
procedure _printDouble(d: Double); cdecl;
begin
Writeln(d);
end;
procedure test(arr: PDouble; count: Integer); cdecl; external name '_test';
{$L testarray.obj}
var
arr: TArray<Double>;
begin
arr := TArray<Double>.Create(1.0, 2.0, 3.0, 42.0, 666.0);
test(PDouble(arr), Length(arr));
Readln;
end.
Compile the C code using, for example, the Borland C compiler like this:
bcc32 -c testarray.c
And the output is:
1.00000000000000E+0000
2.00000000000000E+0000
3.00000000000000E+0000
4.20000000000000E+0001
6.66000000000000E+0002
Note that I linked to the C code statically because that was easier for me. Nothing much changes if you put the C code in a DLL.
The conclusion is that the code I gave you in my answer to your previous, and that I repeat here, is correct. That approach succeeds in passing an array from Delphi code to C. It looks like your diagnostics and debugging is in error.
You are only inspecting A[0] so it's hardly surprising that you only see one value. If only you would look at A[1], A[2], ... , A[n-1] you would see that that all the values are being passed correctly. Or perhaps your debugging was carried out on the erroneous declaration of the external function that used TArray<T> as a parameter.
How to deal with double pointers in VFP for calling c based DLL
I have a c language DLL which has parameters of double pointer as given below
int fun_foo(char *str1,char **str2) //str2 has some info. when returns from function
In FoxPro I am trying to call this function from its DLL. How can I can call this; I tried as :
DECLARE INT fun_foo IN sample.dll STRING,STRING #
I found that char* can be passed with string parameter but i have difficulty with double pointer string# is not working.
Can anyone give clue how to pass parameter in Visual foxpro for a double pointer param in c function(DLL)
the data i get from the function in this double pointer is important for me
I am using Visual FoxPro 9.0 SP1 and DLL is of 32 bit made on visual c++ 2005
Thanks in Advance
Short answer:
Use vfp2c32.fll
http://vfpx.codeplex.com/releases/view/71594
From the help file:
ReadPointer
Retrieves a pointer from the specified address.
Long answer:
If you want to do it only with VFP, check SYS(2600), BINTOC, CTOBIN and strncpy (that last one is in the c runtime that you need anyway to run VFP executables.)
DECLARE INTEGER fun_foo IN sample.dll ;
STRING str1,;
INTEGER #pointer
m.str1 = "sometext"
m.pointer = 0
m.result = fun_foo(m.str2, #m.pointer)
Now what is in that pointer? you don't say. A NUL terminated string? use strncpy. An INT or some fixed length string? Use sys(2600)
I don't know that it can be done from Foxpro itself, but maybe you could (if you're proficient in C) create an intermediate ActiveX object or the like in C, which dereferences your double pointer, and returns it to VFP?
I quite new to fortran .And i am using a lib built in fortran , the lib has many TYPE arrays.
I try to assign the values to the TYPE arrays in the lib through a c program using the following method.
I have built a c-fortran interface where i get values from a sqlite database into a c structure array in c prg.Then pass this structure array it to a fortran subroutine where i declare it as a derived type, matching the definition of TYPE variable declared in the lib .Then i copy the values from the passed arrays to actual TYPE arrays declared in the lib and pass it to fortran function .
What is happening is the values in the arrays are passed ok from c to fortran subroutine , i print them to check them in fortran subroutine, but the values are getting garbled when the arrays are passed from the subroutine to the function . I am passing the arrays as assumed shaped array. The function is declared inside a module hence i thought the calling subroutine will not require an interface .
I am not exactly understanding what is happening , i have also tried using the sequence in the TYPE declaration .
I am using g95 , gcc 4.0.3 complilers.
All the values in the arrays are of type REAL(KIND =8) , and the equivalent in the c program is double .
Consider a lib which has TYPE(something), TYPE(Something2) declared in it. I import the lib as a module in a fortran subroutine .
Lets assume
TYPE(something_lib) is
REAL(kind =8) ::A
REAL(kind=8) ::B
END TYPE
in the lib
TYPE(SOMETHING2_lib) !this is also declare in the lib
!I have a C program in which
! in which
///////////////////////////////////////////////////////////////////////////////////////////
// C program
struct SomethingC
{
double a
double b
} ;
struct SomethingC x[2]
struct something2C s[2] // something similar to the first struct
//i fill the values in x ,s from database in proper format.(doubles).
//i call the fortran subroutine in the c program
A_(x,s); //call to fortran subroutine
///////////////////////////////////////////////////////////////////////////////////////////
// the fortan subroutine
SUBROUTINE A (x,s)
USE Lib_module ! this LIB_Module also contains the function func
TYPE G
REAL(kind =8) ! this is defined similar to TYPE something(in lib) by me
REAL(kind =8)
END TYPE G
TYPE G2
similar to TYPE Something2 in lib
END TYPE G2
TYPE(something_lib) :: D(2) !derived type declared in lib
TYPE(Something2_lib)::E(2) ! derived type declared in lib
TYPE(G)::x(2)
TYPE(G2)::s(2)
! x, s are struct arrays from c which are now declared in the fortran function
copy code for
copying values from
x to D
s to E
print all values of
D
Print all values of
E
!this prints the values correct as expected for both x,d
func(D,E) ! this function is defined in the lib . The function is in the
! LIB_module
! so no interface will be required (i think)
! IN the Function
FUNCTION func(D,E) (while debugging)
TYPE(something_lib) :: INTENT (IN) D(:)
TYPE (something2_lib)::INTENT (IN) E(:)
when i try to print values of D , E in the
function i get garbled values like
1180333333
2.33419537006E-313
!when out of the function and back in the subroutine i.e after the call(while debugging)
! if I print the values of D,E here they print ok
END SUBROUTINE
Thus they are getting garbled after they are passed in the function , but are ok in the
subroutine .
My question is why is this happening ?
how can i solve it?
I suggest using the ISO C Binding, which makes passing variables between C & Fortran part of the Fortran language standard. This will require gcc/gfortran 4.3 or higher; I'm not sure about g95 versions. However, assumed-shaped arrays as arguments to C are not supported. Assumed-shaped arrays are high-level, containing not just the array but info about the size, and passing them to C would probably require understanding the internals of a particular Fortran compiler.