问题描述
我正在将 lib 从 delphi 重写为 c#。在delphi客户端调用library方法,参数如下
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);
tVector.SetValue(Tmax,1);
object T = tVector;
然后扔掉
System.Runtime.InteropServices.SEHException:“外部组件抛出异常。”
然后像这样尝试:
Array tVector1 = Array.CreateInstance(typeof(double),new[] { 1 },new[] { 1 });
Array tVector2 = Array.CreateInstance(typeof(double),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:“指定的数组不是预期的类型。”
初始化条件:
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,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');
解决方法
找到您所引用的内容:mov cr,reg
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 = 整数 - 完成代码。
和
TModelHandle = THandle – 指向模型的指针;
所以我想说 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);