我在Delphi中有一个代码我使用它来从我的2D阅读器获取图片,我使用'camlib.dll'来设置设备中Image的参数代码:
unit Test_Cam;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TByteArr = array of byte;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ComboBox1: TComboBox;
procedure Button1Click(Sender: TObject);
procedure Doconnect;
procedure CamOpen;
Function StrToByte(const Value: String): TByteArr;
private
{ Private declarations }
public
published
property ObjectMenuItem;
{ Public declarations }
end;
TconfigPort = record
BaudRate:Integer; // baud rate
ByteSize:Integer; // number of bits/byte, 4-8
Parity:Integer; // 0-4=no,odd,even,mark,space
StopBits:Integer; // 0,1,2 = 1, 1.5, 2
fOutxCtsFlow:Integer; // CTS Flow Control
end;
TPROGRESS_FUNC = procedure (blocks_total,blocks_done:Integer) of Object;
var
Form1: TForm1;
Function MetrocomEnterImageUpl(nport:Integer):Boolean; external 'metrocom.dll';
procedure MetrocomAcquireFullFrame(nport:Integer); external 'metrocom.dll';
Function MetrocomUploadJpeg(nPort:Integer; PROGRESS_FUNC:Tprogress_func; szFileName:string; nSubsampling:integer):Boolean; stdcall; external 'metrocom.dll';
Function MetrocomExitImageUpl(nPort:Integer):Boolean; stdcall; external 'metrocom.dll';
Function MetrocomInitCommunication(nPort:Integer; const COMMPORTCONFIG:TconfigPort):Boolean;stdcall; external 'metrocom.dll';
Function MetrocomEndCommunication(nPort:Integer):Boolean; stdcall; external 'metrocom.dll';
Function camSetImageCompression(cam_handle:Integer; quality:Integer; method:Integer):Integer;stdcall; external 'Camlib.dll';
Function camSetCenteredWOI(cam_handle:Integer;img_width:Integer;img_height:Integer):Integer; stdcall; external 'Camlib.dll';
Function camInit(dev_interface:Integer):Integer; stdcall; external 'Camlib.dll';
Function camOpenEx2(device_name:TByteArr;ctl_bus_name:TByteArr;Var p_dev_type:Integer; ctl_bus_type:integer; camera_type:integer;dev_bus_type:Integer):Integer; stdcall; external 'Camlib.dll';
Function camClose(cam_handle:Integer):Integer; stdcall; external 'Camlib.dll';
Function camFree:Integer; stdcall; external 'Camlib.dll';
Function camGetOperatingMode(cam_handle:Integer; var mode:Integer):Integer; stdcall; external 'Camlib.dll';
var
Config_port: TconfigPort;
m_bConnect:Boolean = false;
tt,m_nPort,m_nInit,nPort,i,j,m_camHandle:integer;
nDeviceType:Integer = 0;
device_name:string;
szDeviceName:TByteArr;
implementation
{$R *.dfm}
function TForm1.StrToByte(const Value: String): TByteArr;
var
I: integer;
begin
SetLength(Result, Length(Value));
for I := 0 to Length(Value) - 1 do
Result[I] := ord(Value[I + 1]) ;
end;
procedure Tform1.DoConnect;
begin
m_nPort := StrToInt(ComboBox1.Text) - 1;
Config_port.BaudRate := 9600;
Config_port.ByteSize := 8;
Config_port.Parity := 0;
Config_port.StopBits := 0;
m_bConnect := MetrocomInitCommunication(m_nPort , Config_port);
end;
procedure TForm1.CamOpen;
begin
m_nInit := camInit(0);
if m_nInit < 0 then
ShowMessage('Fail to camInit.');
nPort := m_nPort + 1;
device_name := 'COM' + IntToStr(nPort) + ' baud=' + IntToStr(Config_port.BaudRate) + ' parity=' + IntToStr(Config_port.Parity) + ' data=' + IntToStr(Config_port.ByteSize) + ' stop=' + IntToStr(Config_port.StopBits);
szDeviceName := strtobyte(device_name);
for i := 0 to 4 do
begin
for j := 0 to 4 do
begin
m_camHandle := camOpenEx2(szDeviceName, nil , nDeviceType, 0, 1, 16);
if m_camHandle > 0 then break;
end;
if m_camHandle > 0 then break;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DoConnect;
CamOpen;
tt := camSetImageCompression(m_camHandle, 30, 2);
camSetCenteredWOI(m_camHandle, 500, 220);
end;
end.
我在这行中得到一个Erorr并且编译了两个函数后发生错误我得到一个错误,即“0x000001f4处的访问冲突:读取地址0x000001f4”然后在delphi中打开CPU debuging:
tt := camSetImageCompression(m_camHandle, 30, 2);
camSetCenteredWOI(m_camHandle, 500, 220);
camlib.dll中函数的描述是:
camSetImageCompression
This function sets the image compression parameters.
Prototype:
int camSetImageCompression (int cam_handle, int quality, int method);
Parameters:
cam_handle - [in] handle to the camera device returned by the camOpen function.
quality - [in] allowable value of image quality after compression: 1(worst) - 100(best)
method - [in] allowable compression method. Currently, this parameter can be one of the
following values:
CAMLIB_COMPRESS_NONE no compression;
CAMLIB_COMPRESS_SUBSAMPLE image resampling down;
CAMLIB_COMPRESS_JPEG JPEG compression;
CAMLIB_COMPRESS_ANY any method of compression;
Return Value:
0: Success; -1: Failure
camSetCenteredWOI
This function sets the window of interest (WOI) of the given size centered horizontally and vertically in the
field of view of the camera.
Prototype:
int camSetCenteredWOI (int cam_handle, int img_width, int img_height);
Parameters:
cam_handle - [in] handle to the camera device returned by the camOpen function.
img_width - [in] image width, in pixels.
img_height - [in] image height, in rows.
Return Value:
0: Success; -1: Failure
camOpenEx2
This function establishes communication with the specified camera device.
Prototype:
int camOpenEx2 (char *device_name, char *ctl_bus_name, int *p_dev_type, int ctl_bus_type,
intcamera_type, int dev_bus_type);
Parameters:
device_name - [in] camera communication device name optionally followed by a device-control
string that contains communication parameters. Currently, the device name must
be a valid serial port. For example, the following string specifies the COM1
communication port, a baud rate of 9600, no parity, 8 data bits, and 1 stop bit:
COM1: baud=9600 parity=N data=8 stop=1. If the communication device is USB
then the device_name parameter should be 0.
ctl_bus_name - [in] should be NULL.
p_dev_type - [out] (optional) pointer to the location where the function returns the type of image
sensor used in the camera. Currently, this value can only be
CAM_IMG_SENSOR_MT9M001C or CAM_IMG_SENSOR_VC5602 (or
CAM_IMG_SENSOR_UNKNOW N if the sensor type could not be automatically
identified).
ctl_bus_type - [in] should be 0.
camera_type - [in] camera type. Currently, this value can only be
CAMLIB_CAMERATYPE_FOCUS, CAMLIB_CAMERATYPE_ORBIT3 or
CAMLIB_CAMERATYPE_VUQUEST.
dev_bus_type - [in] device bus type. Currently, this value can only be CAMLIB_BUSTYPE_RS232
or CAMLIB_BUSTYPE_USB20.
Return Value:
If positive handle to the camera device, or (-1) in case of error. The handle must be used in all
consequent calls to CamLib APIs to identify the camera device on which an operation is requested
to be performed.
在C#中工作正常:
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;
using System.Reflection;
namespace Sample
{
public partial class frmMain : Form
{
public struct COMMPORTCONFIG
{
public int BaudRate; // baud rate
public int ByteSize; // number of bits/byte, 4-8
public int Parity; // 0-4=no,odd,even,mark,space
public int StopBits; // 0,1,2 = 1, 1.5, 2
int fOutxCtsFlow; // CTS Flow Control
}
[DllImport(@"C:\WINDOWS\metrocom.dll", EntryPoint = "MetrocomEnterImageUpl")]
extern public static bool MetrocomEnterImageUpl(int nPort);
[DllImport(@"C:\WINDOWS\metrocom.dll", EntryPoint = "MetrocomAcquireFullFrame")]
extern public static void MetrocomAcquireFullFrame(int nPort);
public delegate void PROGRESS_FUNC(int blocks_total, int blocks_done);
[DllImport(@"C:\WINDOWS\metrocom.dll", EntryPoint = "MetrocomUploadJpeg")]
extern public static bool MetrocomUploadJpeg(int nPort, PROGRESS_FUNC p_progress_func, char[] szFileName, int nSubsampling);
[DllImport(@"C:\WINDOWS\metrocom.dll", EntryPoint = "MetrocomExitImageUpl")]
extern public static bool MetrocomExitImageUpl(int nPort);
[DllImport(@"C:\WINDOWS\metrocom.dll", EntryPoint = "MetrocomInitCommunication")]
extern public static bool MetrocomInitCommunication(int nPort, ref COMMPORTCONFIG p_config);
[DllImport(@"C:\WINDOWS\metrocom.dll", EntryPoint = "MetrocomEndCommunication")]
extern public static bool MetrocomEndCommunication(int nPort);
[DllImport(@"C:\WINDOWS\Camlib.dll", EntryPoint = "camSetImageCompression")]
extern public static int camSetImageCompression(int cam_handle, int quality, int method);
[DllImport(@"C:\WINDOWS\Camlib.dll", EntryPoint = "camSetCenteredWOI")]
extern public static int camSetCenteredWOI(int cam_handle, int img_width, int img_height);
[DllImport(@"C:\WINDOWS\Camlib.dll", EntryPoint = "camInit")]
extern public static int camInit(int dev_interface);
[DllImport(@"C:\WINDOWS\Camlib.dll", EntryPoint = "camOpenEx2")]
public extern static int camOpenEx2(byte[] device_name, byte[] ctl_bus_name, ref int p_dev_type, int ctl_bus_type, int camera_type, int dev_bus_type);
[DllImport(@"C:\WINDOWS\Camlib.dll", EntryPoint = "camClose")]
extern public static int camClose(int cam_handle);
[DllImport(@"C:\WINDOWS\Camlib.dll", EntryPoint = "camFree")]
extern public static int camFree();
[DllImport(@"C:\WINDOWS\Camlib.dll", EntryPoint = "camGetOperatingMode")]
extern public static int camGetOperatingMode(int cam_handle, ref int mode);
//[DllImport(@"C:\WINDOWS\Camlib.dll", EntryPoint = "camReadData")]
//extern public static int camReadData (int cam_handle, int ibus,
// char *buf,int cb_to_read, int *cb_read,int *fcancel, long ms_timeout, long ms_idle_timeout);
[DllImport(@"C:\WINDOWS\metrocom.dll", EntryPoint = "MetrocomReadData")]
extern public static bool MetrocomReadData(long i_port, string buf, long dw_bufsize, long fcancel,
long wait_timeout, long read_timeout);
[DllImport(@"C:\WINDOWS\GetSN.dll", EntryPoint = "CheckValid")]
extern public static bool CheckValid();
int m_nPort = -1;
COMMPORTCONFIG p_config = new COMMPORTCONFIG();
int m_camHandle = -1;
int m_nInit = -1;
bool m_bConnect = false;
string m_strPath = System.IO.Directory.GetCurrentDirectory();
int m_nMode = -1;
public frmMain()
{
InitializeComponent();
}
private void Connect_Click(object sender, EventArgs e)
{
if (Connect.Text.Trim() == "connect")
{
DoConnect();
CamOpen();
IsConnet();
camSetImageCompression(m_camHandle, 30, 0x002);
camSetCenteredWOI(m_camHandle, 500, 220);
Shapshot.Enabled = true;
textBox1.Focus();
//Shapshot_Click(sender, e);
}
else
{
DoDisconnect();
CamCloe();
}
}
private void Shapshot_Click(object sender, EventArgs e)
{
if (textBox1.Text.Trim() == "")
{
MessageBox.Show("chose the name please");
textBox1.Focus();
}
else
{
GetOperatingMode();
if (m_nMode == 0)
{
PROGRESS_FUNC test = new PROGRESS_FUNC(progress_function);
bool bResult = MetrocomEnterImageUpl(m_nPort);
MetrocomAcquireFullFrame(m_nPort);
//string strPath = Application.ExecutablePath;
string strFileName = m_strPath + "\\" + textBox1.Text + "1.jpg";
char[] szFileName = strFileName.ToCharArray(0, strFileName.Length);
bool bTemp = false;
if (bResult)
bTemp = MetrocomUploadJpeg(m_nPort, test, szFileName, 0);
}
MetrocomExitImageUpl(m_nPort);
if (MessageBox.Show("another Side ", "Take picture",
MessageBoxButtons.OKCancel, MessageBoxIcon.Question)
== DialogResult.OK)
{
GetOperatingMode();
if (m_nMode == 0)
{
PROGRESS_FUNC test = new PROGRESS_FUNC(progress_function);
bool bResult = MetrocomEnterImageUpl(m_nPort);
MetrocomAcquireFullFrame(m_nPort);
//string strPath = Application.ExecutablePath;
string strFileName = m_strPath + "\\" + textBox1.Text + "2.jpg";
char[] szFileName = strFileName.ToCharArray(0, strFileName.Length);
bool bTemp = false;
if (bResult)
bTemp = MetrocomUploadJpeg(m_nPort, test, szFileName, 0);
}
textBox1.Text = "";
}
}
}
private void frmMain_Load(object sender, EventArgs e)
{
string[] szArray = new string[256];
for (int i = 0; i < szArray.Length; i++)
{
szArray[i] = "Com" + i;
}
cmbPort.DataSource = szArray;
cmbPort.SelectedIndex = 3;
bool valid = CheckValid();
if (valid == false)
{
Application.Exit();
}
}
private void DoConnect()
{
string strTemp = cmbPort.Text.Trim();
string[] parts = strTemp.Split('m');
m_nPort = Convert.ToInt16(parts[1]) - 1;
p_config.BaudRate = 9600;
p_config.ByteSize = 8;
p_config.Parity = 0;
p_config.StopBits = 0;
m_bConnect = MetrocomInitCommunication(m_nPort, ref p_config);
}
private void CamOpen()
{
m_nInit = camInit(0);
if (m_nInit < 0)
MessageBox.Show("Fail to connect");
int nPort = m_nPort + 1;
string device_name;
device_name = "COM" + nPort + " baud=" + p_config.BaudRate + " parity=" + p_config.Parity + " data=" + p_config.ByteSize + " stop=" + p_config.StopBits;
int nDeviceType = 0;
int i, j;
byte[] szDeviceName = System.Text.Encoding.Default.GetBytes(device_name);
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
m_camHandle = camOpenEx2(szDeviceName, null, ref nDeviceType, 0, 1, 0x0010);
if (m_camHandle > 0)
break;
}
if (m_camHandle > 0)
break;
}
}
private void CamCloe()
{
if (m_camHandle >= 0)
camClose(m_camHandle);
if (m_nInit == 0)
camFree();
}
private void DoDisconnect()
{
if (m_bConnect)
MetrocomEndCommunication(m_nPort);
Connect.Text = "connect";
cmbPort.Enabled = true;
}
private void IsConnet()
{
if (!m_bConnect || m_camHandle <= 0)
MessageBox.Show("Fail to connect to Fcous.", "UnitechVision");
else
{
cmbPort.Enabled = false;
Connect.Text = "connected";
}
}
private int GetOperatingMode()
{
camGetOperatingMode(m_camHandle, ref m_nMode);
return m_nMode;
}
void progress_function(int blocks_total, int blocks_done)
{
blocks_total = 30;
blocks_done = 50;
}
private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
{
if (m_camHandle > 0)
camClose(m_camHandle);
if (m_nInit == 0)
camFree();
if (m_bConnect)
MetrocomEndCommunication(m_nPort);
}
private void button1_Click(object sender, EventArgs e)
{
string s = @"d:\12\1.jpg";
pictureBox1.Load(s);
}
}
}
答案 0 :(得分:1)
camSetImageCompression
和camSetCenteredWOI
的翻译准确无误。那里没有错。
问题是camOpenEx2
。你使用Delphi管理的动态数组类型。这对互操作无效。现在,我们无法确定camOpenEx2
的C声明应该是什么,但是全局变量szDeviceName
的名称非常强烈地表明文本参数是char*
,这是指向以null结尾的8位字符数组。
在这种情况下,您可以像这样声明camOpenEx2
:
Function camOpenEx2(
device_name: PAnsiChar;
ctl_bus_name: PAnsiChar;
Var p_dev_type: Integer;
ctl_bus_type: Integer;
camera_type: Integer;
dev_bus_type: Integer
): Integer; stdcall; external 'Camlib.dll';
你这样称呼它:
m_camHandle := camOpenEx2(PAnsiChar(DeviceName), nil, nDeviceType, 0, 1, 16);
请注意,我假设您声明的其余部分是正确的。我无法检查,因为您没有显示camOpenEx2
的C声明。
我也无法确定第二个参数的nil
传递是否有效。也许你应该传递一个空字符串,在这种情况下你会传递''
。 更新: C#代码似乎表明传递nil
是可以接受的。
另请注意,我假设您使用的是Unicode前Delphi。但如果没有,那就是如果你有Delphi 2009或更高版本,那么你需要将DeviceName
声明为AnsiString
而不是string
。
现在,可能还有其他错误。这是互操作的,并且需要人来确保互操作接口的两侧匹配。您展示了camSetImageCompression
和camSetCenteredWOI
的另一面,并确保您的翻译准确无误。对于互操作,确保动态数组不正确。但我不能检查,因为我只能看到互操作界面的一面。
<强>更新强>
C#清除了一点,但代码也错了。具体来说,它对byte和char数组的使用是不正确的。我猜想.net框架偶然会分配内存,而这些内存恰好在数组的末尾有空终结符。
我认为MetrocomUploadJpeg
看起来很可疑。那char[]
似乎不合理。但是你没有打电话给它,所以不要挂断它。至于其余的导入,它们匹配p / invokes。好吧,如上所述更改camOpenEx2
。
C#代码看起来非常脆弱。坦率地说,我认为你最好从原始文档和C ++示例开始。我不知道C#代码来自哪里,但它做得不好。