将多维数组从 c# 编组到 delphi
Marshalling Multidimensional arrays from c# to delphi
我正在将 lib 从 delphi 重写为 c#。库方法在delphi客户端调用,参数如下
T:=VarArrayCreate([1,2,1,1],varDouble);
T[1,1]:=Tmin;
T[2,1]:=Tmax;
我试过像这样将相同的数组传递给 c#:
Array tVector = Array.CreateInstance(typeof(double), new[] { 2, 1 }, new[] { 1, 1 });
tVector.SetValue(Tmin, 1, 1);
tVector.SetValue(Tmax, 2, 1);
object T = tVector;
然后扔出去
System.Runtime.InteropServices.SEHException: "External component has thrown an exception."
然后这样尝试:
Array tVector1 = Array.CreateInstance(typeof(double), new[] { 1 }, new[] { 1 });
Array tVector2 = Array.CreateInstance(typeof(double), new[] { 1 }, new[] { 1 });
Array tVector = Array.CreateInstance(tVector1.GetType(), new[] { 2 }, new[] { 1 });
tVector.SetValue(tVector1, 1);
tVector.SetValue(tVector2, 2);
object T = tVector;
然后扔出去
System.Runtime.InteropServices.SafeArrayTypeMismatchException: "Specified array was not of the expected type."
初始条件:
c#调用delphi方法:
function call (hModel: TModelHandle; const FunName: variant; var Params: variant; var Res: variant): TRetCode; stdcall;
Params 是一维变量数组。我准备如下:
public object Call(string functionName, params object[] parameters)
{
object res = new();
object funName = functionName;
Array endParamsArray = Array.CreateInstance(typeof(object), new[] {parameters.Length}, new[] {1});
Array.Copy(parameters, endParamsArray, parameters.Length);
object endParams = endParamsArray;
var rc = call(hModel, ref funName, ref endParams, ref res);
if (rc != TRetCode.rcOK)
error(rc);
return res;
}
然后我打电话给:
object T = tVector;
PM.Call("funname", ID, Name, T, RamStab, Ktrans, sec_overcoming);
当传递的参数很简单时:int、string 等。一切正常。但是传递一个数组我得到一个异常
这是 Delphi 上的客户端代码,其中一切正常:
w:='funname'; FunName:=w;
Params:=VarArrayCreate([1,6],varVariant);
Params[1]:=ID;
Params[2]:=Name;
T:=VarArrayCreate([1,2,1,1],varDouble);
T[1,1]:=Tmin;
T[2,1]:=Tmax;
Params[3]:=T;
Params[4]:=RamStab;
Params[5]:=Ktrans;
Params[6]:=sec_overcoming;
rc:=PM.call(PM.hModel,FunName,Params,Res);
Bar:=PM.getObject(Name);
if Bar=nil then
error('create');
找到您引用的内容:https://www.mvstudium.com/eng/RMDmanual-en.pdf
function call (hModel: TModelHandle; const FunName: variant; var Params: variant; var Res: variant): TRetCode; stdcall;
TRetCode __stdcall call (TModelHandle hModel, variant *FunName, variant *Params, variant *Res);
在哪里
TRetCode = integer – completion code.
和
TModelHandle = THandle – pointer to a model;
所以我会说 TModelHandle
是一个 IntPtr
(32 位有 32 位进程,64 位有 64 位进程)。所以:
[DllImport(@"Yourdll", CallingConvention = CallingConvention.StdCall)]
public static extern int call(IntPtr hModel, ref object funName, ref object @params, ref object res);
public static object Call(string functionName, params object[] parameters)
{
object res = null;
object funName = functionName;
Array endParamsArray = Array.CreateInstance(typeof(object), new[] { parameters.Length }, new[] { 1 });
Array.Copy(parameters, endParamsArray, parameters.Length);
object endParams = endParamsArray;
var rc = call(hModel, ref funName, ref endParams, out res);
return res;
}
我已经构建了一个 C#->C++ 代码,其中包含为 C++ 提议的签名,并且它可以正常工作。参数传递正确,res
正确传递出去
double Tmin = double.MinValue;
double Tmax = double.MaxValue;
int ID = 1;
string Name = "Foo";
double RamStab = 5;
long Ktrans = 3;
int sec_overcoming = 2;
Array tVector = Array.CreateInstance(typeof(double), new[] { 2, 1 }, new[] { 1, 1 });
tVector.SetValue(Tmin, 1, 1);
tVector.SetValue(Tmax, 2, 1);
object response = Call("Hello world", ID, Name, tVector, RamStab, Ktrans, sec_overcoming);
我正在将 lib 从 delphi 重写为 c#。库方法在delphi客户端调用,参数如下
T:=VarArrayCreate([1,2,1,1],varDouble);
T[1,1]:=Tmin;
T[2,1]:=Tmax;
我试过像这样将相同的数组传递给 c#:
Array tVector = Array.CreateInstance(typeof(double), new[] { 2, 1 }, new[] { 1, 1 });
tVector.SetValue(Tmin, 1, 1);
tVector.SetValue(Tmax, 2, 1);
object T = tVector;
然后扔出去
System.Runtime.InteropServices.SEHException: "External component has thrown an exception."
然后这样尝试:
Array tVector1 = Array.CreateInstance(typeof(double), new[] { 1 }, new[] { 1 });
Array tVector2 = Array.CreateInstance(typeof(double), new[] { 1 }, new[] { 1 });
Array tVector = Array.CreateInstance(tVector1.GetType(), new[] { 2 }, new[] { 1 });
tVector.SetValue(tVector1, 1);
tVector.SetValue(tVector2, 2);
object T = tVector;
然后扔出去
System.Runtime.InteropServices.SafeArrayTypeMismatchException: "Specified array was not of the expected type."
初始条件:
c#调用delphi方法:
function call (hModel: TModelHandle; const FunName: variant; var Params: variant; var Res: variant): TRetCode; stdcall;
Params 是一维变量数组。我准备如下:
public object Call(string functionName, params object[] parameters)
{
object res = new();
object funName = functionName;
Array endParamsArray = Array.CreateInstance(typeof(object), new[] {parameters.Length}, new[] {1});
Array.Copy(parameters, endParamsArray, parameters.Length);
object endParams = endParamsArray;
var rc = call(hModel, ref funName, ref endParams, ref res);
if (rc != TRetCode.rcOK)
error(rc);
return res;
}
然后我打电话给:
object T = tVector;
PM.Call("funname", ID, Name, T, RamStab, Ktrans, sec_overcoming);
当传递的参数很简单时:int、string 等。一切正常。但是传递一个数组我得到一个异常
这是 Delphi 上的客户端代码,其中一切正常:
w:='funname'; FunName:=w;
Params:=VarArrayCreate([1,6],varVariant);
Params[1]:=ID;
Params[2]:=Name;
T:=VarArrayCreate([1,2,1,1],varDouble);
T[1,1]:=Tmin;
T[2,1]:=Tmax;
Params[3]:=T;
Params[4]:=RamStab;
Params[5]:=Ktrans;
Params[6]:=sec_overcoming;
rc:=PM.call(PM.hModel,FunName,Params,Res);
Bar:=PM.getObject(Name);
if Bar=nil then
error('create');
找到您引用的内容:https://www.mvstudium.com/eng/RMDmanual-en.pdf
function call (hModel: TModelHandle; const FunName: variant; var Params: variant; var Res: variant): TRetCode; stdcall;
TRetCode __stdcall call (TModelHandle hModel, variant *FunName, variant *Params, variant *Res);
在哪里
TRetCode = integer – completion code.
和
TModelHandle = THandle – pointer to a model;
所以我会说 TModelHandle
是一个 IntPtr
(32 位有 32 位进程,64 位有 64 位进程)。所以:
[DllImport(@"Yourdll", CallingConvention = CallingConvention.StdCall)]
public static extern int call(IntPtr hModel, ref object funName, ref object @params, ref object res);
public static object Call(string functionName, params object[] parameters)
{
object res = null;
object funName = functionName;
Array endParamsArray = Array.CreateInstance(typeof(object), new[] { parameters.Length }, new[] { 1 });
Array.Copy(parameters, endParamsArray, parameters.Length);
object endParams = endParamsArray;
var rc = call(hModel, ref funName, ref endParams, out res);
return res;
}
我已经构建了一个 C#->C++ 代码,其中包含为 C++ 提议的签名,并且它可以正常工作。参数传递正确,res
正确传递出去
double Tmin = double.MinValue;
double Tmax = double.MaxValue;
int ID = 1;
string Name = "Foo";
double RamStab = 5;
long Ktrans = 3;
int sec_overcoming = 2;
Array tVector = Array.CreateInstance(typeof(double), new[] { 2, 1 }, new[] { 1, 1 });
tVector.SetValue(Tmin, 1, 1);
tVector.SetValue(Tmax, 2, 1);
object response = Call("Hello world", ID, Name, tVector, RamStab, Ktrans, sec_overcoming);