错误提示:
project project11.exe raised exception class EOleException with message 秩为0的 SafeArray 被传递到需要秩为1的数组的方法中。 Delphi代码如下:
unit Unit10;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, activex,
DB, ADODB,Grids, DBGrids, DBClient, StdCtrls, Provider,
frmByteArrayToDelphi_TLB, Dialogs;type
TForm10 = class(TForm)
Button1: TButton;
DBGrid1: TDBGrid;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; Type
byteArrayP=^byteArray;
byteArray=array [0..0] of byte;
type
mybuffer=array [0..1023] of byte;
var
Form10: TForm10;implementation{$R *.dfm}procedure TForm10.Button1Click(Sender: TObject);
var
{
mydataset:tclientdataset;
mydatasource:tdatasource;
myprovider: tdatasetprovider;
myquery:tadoquery;
sqlcmd:TStringList;ms1,ms2,ms3:TMemoryStream;
}ttest:Interface1;a,b, len:integer;
buf:mybuffer;
s:string;
//buf2:bytearrayp;buf3:psafearray;begin
//buf2:=allocmem(1024);
//zeromemory(buf2,1024);
buf3:=allocmem(1024);
zeromemory(buf3,1024);
ttest:=CoForm1.Create() AS INTERFACE1;len:= ttest.getByteArray ; //正常返回 1024;
ttest.fillBytes(buf3); //这里报错:秩为0的 SafeArray 被传递到需要秩为1的数组的方法中end;end.上述代码调用 VS C# dll ,读取一个数组的长度(该方法正常),填充一个byte[](该方法报错);
VS C# dll 的代码如下:
1、接口代码using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace frmByteArrayToDelphi
{
[Guid("208F6752-E99B-4614-857B-0DA442C338C2")]
public interface Interface1
{
int getByteArray();
void fillBytes(byte[] btz);
}
}
Class代码:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace frmByteArrayToDelphi
{
[Guid("2F6CC041-F319-408D-A544-C4CF5930D21E")]
public partial class Form1 : Form, Interface1
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
// byte [] mybt=getByteArray ();
} byte[] btTest = new byte[1024]; public void setByteArray()
{
for (int i = 0; i < btTest.Length; i++)
{
btTest[i] = (byte )i; }
} public int getByteArray()
{
setByteArray();
return btTest.Length ;
} public void fillBytes(byte[] btz)
{
for (int i = 0; i < btz.Length; i++)
{
btz [i ]=(byte)i;
}
// return btz ;
}
}
}上述vsC# dll 编译和注册均正常,Delphi 6调用也正常。在delphi中执行fillBytes(buf3) 时候报错:
project project11.exe raised exception class EOleException with message 秩为0的 SafeArray 被传递到需要秩为1的数组的方法中。 附:《Delphi调用vs dll的步骤》
=====================《Delphi调用vs dll的步骤》===============================
1、编写VS dll
1.1 获取[Guid("xxx-xxx-xxx-xxx-xx0a")]
1.2 按照如下形式写接口 和 类
---------------------------------------
using System.Runtime.InteropServices;
[Guid("xxx-xxx-xxx-xxx-xx0a")]
public interface IAddInterface//自定义接口名字
{
int Add(int i1, int i2);
}
---------------------------------------
using System.Runtime.InteropServices;[Guid("xxx-xxx-xxx-xxx-xx02")]
public class SimpleDLL : IAddInterface//根据需要添加其他父类
{
public int Add(int i1, int i2)
{
return i1+i2;
}
}
1.3编译属性上 选择 对COM可见
1.4编译生成SimpleDll.dll
------------------------------------------
2、 注册dll
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm SimpleDll.dll /tlb:Add.tlb
产生.tlb文件3、在delphi中添加.tlb文件(注意选择register类型)3.1. Open Delphi (in my case 2009) and press menu "View / Registered Type Library"3.2. Use the search feature to confirm that the name is not registered (if any) and Press "Register" and choose the file "Add.tlb" - read the message resulted by the action (if successful, continue further)3.3. Press menu "Component / Import Component", will lead you to wizard to have yourself the _TLB.PAS file
3.4、. On the wizard choose the Registered Class and press next - now (very important) make sure that the Class Name(s) / Non-editable editbox comes up the names that you have put in the C# public
3.5. Press Finish, now the _TLB.PAS file should be present along with any support files produced by the import action4、Delphi下编写调用代码如下格式
procedure TForm1.Button1Click(Sender: TObject);
var
intfRef: IAddInterface;
result: Integer;
begin
intfRef := CLASS_SimpleDLL_.Create() as IAddInterface;
result := intfRef.Add(2, 2);
end;
(注:3.5后会在工程中添加一个新的单元 dll_TLB单元,要引进来)
===============================《完毕》========================================
project project11.exe raised exception class EOleException with message 秩为0的 SafeArray 被传递到需要秩为1的数组的方法中。 Delphi代码如下:
unit Unit10;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, activex,
DB, ADODB,Grids, DBGrids, DBClient, StdCtrls, Provider,
frmByteArrayToDelphi_TLB, Dialogs;type
TForm10 = class(TForm)
Button1: TButton;
DBGrid1: TDBGrid;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; Type
byteArrayP=^byteArray;
byteArray=array [0..0] of byte;
type
mybuffer=array [0..1023] of byte;
var
Form10: TForm10;implementation{$R *.dfm}procedure TForm10.Button1Click(Sender: TObject);
var
{
mydataset:tclientdataset;
mydatasource:tdatasource;
myprovider: tdatasetprovider;
myquery:tadoquery;
sqlcmd:TStringList;ms1,ms2,ms3:TMemoryStream;
}ttest:Interface1;a,b, len:integer;
buf:mybuffer;
s:string;
//buf2:bytearrayp;buf3:psafearray;begin
//buf2:=allocmem(1024);
//zeromemory(buf2,1024);
buf3:=allocmem(1024);
zeromemory(buf3,1024);
ttest:=CoForm1.Create() AS INTERFACE1;len:= ttest.getByteArray ; //正常返回 1024;
ttest.fillBytes(buf3); //这里报错:秩为0的 SafeArray 被传递到需要秩为1的数组的方法中end;end.上述代码调用 VS C# dll ,读取一个数组的长度(该方法正常),填充一个byte[](该方法报错);
VS C# dll 的代码如下:
1、接口代码using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace frmByteArrayToDelphi
{
[Guid("208F6752-E99B-4614-857B-0DA442C338C2")]
public interface Interface1
{
int getByteArray();
void fillBytes(byte[] btz);
}
}
Class代码:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace frmByteArrayToDelphi
{
[Guid("2F6CC041-F319-408D-A544-C4CF5930D21E")]
public partial class Form1 : Form, Interface1
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
// byte [] mybt=getByteArray ();
} byte[] btTest = new byte[1024]; public void setByteArray()
{
for (int i = 0; i < btTest.Length; i++)
{
btTest[i] = (byte )i; }
} public int getByteArray()
{
setByteArray();
return btTest.Length ;
} public void fillBytes(byte[] btz)
{
for (int i = 0; i < btz.Length; i++)
{
btz [i ]=(byte)i;
}
// return btz ;
}
}
}上述vsC# dll 编译和注册均正常,Delphi 6调用也正常。在delphi中执行fillBytes(buf3) 时候报错:
project project11.exe raised exception class EOleException with message 秩为0的 SafeArray 被传递到需要秩为1的数组的方法中。 附:《Delphi调用vs dll的步骤》
=====================《Delphi调用vs dll的步骤》===============================
1、编写VS dll
1.1 获取[Guid("xxx-xxx-xxx-xxx-xx0a")]
1.2 按照如下形式写接口 和 类
---------------------------------------
using System.Runtime.InteropServices;
[Guid("xxx-xxx-xxx-xxx-xx0a")]
public interface IAddInterface//自定义接口名字
{
int Add(int i1, int i2);
}
---------------------------------------
using System.Runtime.InteropServices;[Guid("xxx-xxx-xxx-xxx-xx02")]
public class SimpleDLL : IAddInterface//根据需要添加其他父类
{
public int Add(int i1, int i2)
{
return i1+i2;
}
}
1.3编译属性上 选择 对COM可见
1.4编译生成SimpleDll.dll
------------------------------------------
2、 注册dll
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm SimpleDll.dll /tlb:Add.tlb
产生.tlb文件3、在delphi中添加.tlb文件(注意选择register类型)3.1. Open Delphi (in my case 2009) and press menu "View / Registered Type Library"3.2. Use the search feature to confirm that the name is not registered (if any) and Press "Register" and choose the file "Add.tlb" - read the message resulted by the action (if successful, continue further)3.3. Press menu "Component / Import Component", will lead you to wizard to have yourself the _TLB.PAS file
3.4、. On the wizard choose the Registered Class and press next - now (very important) make sure that the Class Name(s) / Non-editable editbox comes up the names that you have put in the C# public
3.5. Press Finish, now the _TLB.PAS file should be present along with any support files produced by the import action4、Delphi下编写调用代码如下格式
procedure TForm1.Button1Click(Sender: TObject);
var
intfRef: IAddInterface;
result: Integer;
begin
intfRef := CLASS_SimpleDLL_.Create() as IAddInterface;
result := intfRef.Add(2, 2);
end;
(注:3.5后会在工程中添加一个新的单元 dll_TLB单元,要引进来)
===============================《完毕》========================================
可否给出简单的示例 代码?
谢谢
C# dll 代码没有调整,delphi代码调整如下:unit Unit10;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, activex, { Variants,}
DB, ADODB,Grids, DBGrids, DBClient, StdCtrls, Provider,
frmByteArrayToDelphi_TLB, Dialogs;type
TForm10 = class(TForm)
Button1: TButton;
DBGrid1: TDBGrid;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; Type
byteArrayP=^byteArray;
byteArray=array [0..0] of byte;
type
mybuffer=array [0..1023] of byte;
var
Form10: TForm10;implementation{$R *.dfm}
{
function VarToByteArr(Value: Variant; var Buffer: Pointer): Integer;
var
P: Pointer;
Len: Integer;
begin
P := VarArrayLock(Value);
try
Result := VarArrayHighBound(Value, 1);
if Result = 0 then
raise Exception.Create( 'Value不是数组变量 ');
GetMem(Buffer, Result);
Move(P^, Buffer^, Result);
finally
VarArrayUnLock(Value);
end;
end;
}
procedure TForm10.Button1Click(Sender: TObject);
var
ttest:Interface1;
a,b, len:integer;
buf:mybuffer;
s:string;
buf3:psafearray;
var
Arr: Variant;begin
//buf2:=allocmem(1024);
//zeromemory(buf2,1024);
buf3:=allocmem(1024);
zeromemory(buf3,1024);Arr := VarArrayCreate([0, 1023],varbyte );ttest:=CoForm1.Create() AS INTERFACE1;len:= ttest.getByteArray ; //正常返回 1024;
ttest.fillBytes(PSafeArray(VarArrayAsPSafeArray(Arr))); // 这一步能被执行,但是看不到Arr里面的内容。 // VarToByteArr(arr,pointer(buf));
//接下来让我犯难的是 如何把 Arr 中的数据 放回 buf中?end;end.
谢谢SQLDebug_Fan兄台。
最后代码如下:
VS C# DLL代码
1接口代码:using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace frmByteArrayToDelphi
{
[Guid("208F6752-E99B-4614-857B-0DA442C338C2")]
public interface Interface1
{
byte[] getByteArray();()//返回值从 int 改为 byte[] void fillBytes(byte[] btz);
}
}
Class代码:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace frmByteArrayToDelphi
{
[Guid("2F6CC041-F319-408D-A544-C4CF5930D21E")]
public partial class Form1 : Form, Interface1
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
byte[] mybttest = new byte[1000];
fillBytes(mybttest);
MessageBox.Show("dsdf");
// byte [] mybt=getByteArray ();
} byte[] btTest = new byte[1024]; public void setByteArray()
{
for (int i = 0; i < btTest.Length; i++)
{
btTest[i] = (byte )i; }
} public byte[] getByteArray()//返回值从 int 改为 byte[]
{
setByteArray();
return btTest ;
} public void fillBytes(byte[] btz)
{
try
{
for (int i = 0; i < btz.Length; i++)
{
btz[i] = (byte)i;
} }
catch { }
// return btz ;
}
}
}delphi 端 调用代码:unit Unit10;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, activex, { Variants,}
DB, ADODB,Grids, DBGrids, DBClient, StdCtrls, Provider,
frmByteArrayToDelphi_TLB, Dialogs;type
TForm10 = class(TForm)
Button1: TButton;
DBGrid1: TDBGrid;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; type
mybuffer=array [0..1023] of byte;
var
Form10: TForm10;implementation{$R *.dfm}procedure TForm10.Button1Click(Sender: TObject);
var
ttest:Interface1;
mybf:mybuffer;
dp:pointer;
buf3:psafearray;
Arr: Variant;
i:Integer;
begin
buf3:=allocmem(1024); //申请psafearray内存
zeromemory(buf3,1024); //清空内存
zeromemory(@mybf[0],1024); //清空数组ttest:=CoForm1.Create() AS INTERFACE1; //创建接口实例
buf3:= ttest.getByteArray ; //正常返回(调用 接口实例,返回psafearray 指针);CopyMemory(@mybf[0],buf3.pvData ,1024); //从psafearray指针 copy数据到 mybuffer
//CopyMemory(@mybf[0],buf3.pvData ,1024); //从psafearray指针 copy数据到 mybufferend;end.
C#dll的编写 参见0楼附注
谢谢各位顶友。
接分啦。