I ran into some issues with this specific code. The problem has most likely something to do with pointer to member of type Harry stored in a tuple, and a vector with Harrytype variable since all other more simple variants do work.
The error that I get with g++:
main.cpp: In instantiation of 'abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)> [with auto:1 = int Harry::*]':
main.cpp:10:13: required from 'void tuple_foreach_constexpr(const std::tuple<T ...>&, F) [with long unsigned int i = 0; long unsigned int size = 2; F = abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)>; T = {int Harry::*, int* Harry::*}]'
main.cpp:17:82: required from 'void tuple_foreach_constexpr(const std::tuple<_Elements ...>&, F) [with F = abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)>; T = {int Harry::*, int* Harry::*}]'
main.cpp:29:32: required from 'void abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]'
main.cpp:56:27: required from here
main.cpp:31:82: error: use of 'a' before deduction of 'auto'
if constexpr(std::is_pointer<typename std::remove_reference<decltype(a.*x)>::type>::value)
^
main.cpp:33:30: error: invalid type argument of unary '*' (have 'int')
std::cout << *(a.*x) << std::endl;
^~~~~~~
main.cpp:6:6: error: 'void tuple_foreach_constexpr(const std::tuple<T ...>&, F) [with long unsigned int i = 1; long unsigned int size = 2; F = abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)>; T = {int Harry::*, int* Harry::*}]', declared using local type 'abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)>', is used but never defined [-fpermissive]
void tuple_foreach_constexpr(const std::tuple<T...>& tuple, F func)
^~~~~~~~~~~~~~~~~~~~~~~
code:
#include <iostream>
#include <tuple>
#include <vector>
template<size_t i, size_t size, typename F, typename... T>
void tuple_foreach_constexpr(const std::tuple<T...>& tuple, F func)
{
if constexpr(i<size)
{
func(std::get<i>(tuple));
tuple_foreach_constexpr<i+1, size, F, T...>(tuple, func);
}
}
template<typename F, typename... T>
void tuple_foreach_constexpr(const std::tuple<T...>& tuple, F func)
{
tuple_foreach_constexpr<0, std::tuple_size<std::tuple<T...>>::value, F, T...>(tuple, func);
}
template<typename A, typename... B>
void abra
(
const std::vector<A>& a_vector,
const std::tuple<B...>& b_tuple
)
{
for(const auto& a : a_vector)
{
tuple_foreach_constexpr(b_tuple, [&a](const auto &x)
{
if constexpr(std::is_pointer<typename std::remove_reference<decltype(a.*x)>::type>::value)
{
std::cout << *(a.*x) << std::endl;
}
else
{
std::cout << a.*x << std::endl;
} // this does NOT work
//std::cout << a.*x << std::endl; // this does work
});
}
}
struct Harry
{
int a;
int* b;
};
int main()
{
int m = 20;
std::vector<Harry> h_vector = {Harry{10, &m}};
std::tuple t_tuple = std::make_tuple(&Harry::a, &Harry::b);
abra(h_vector, t_tuple);
}
It would be very nice if someone had some tips on how to solve this.
(I know this all looks like it makes no sense why anyone would need to do this. However, my priority is not to write good, usable code but to learn stuff and also I really want to get this architecture I had in mind to work.)
It would be very nice if someone had some tips on how to solve this.
First of all: I reproduce your error with g++ but my clang++ (7.0.1) compile your code without problem.
Who's right? g++ or clang++?
I'm not a language lawyer and I'm not sure but I suspect it's a g++ bug.
What is saying g++?
It's saying that in this loop
for(const auto& a : a_vector)
{
tuple_foreach_constexpr(b_tuple, [&a](const auto &x)
{
if constexpr(std::is_pointer<typename std::remove_reference<decltype(a.*x)>::type>::value)
{
std::cout << *(a.*x) << std::endl;
}
else
{
std::cout << a.*x << std::endl;
} // this does NOT work
//std::cout << a.*x << std::endl; // this does work
});
}
the a variable, that is an auto variable (const auto& a : a_vector) so it's type must be deduced by the compiler, that is captured inside the lambda function, is used (decltype(a.*x)) before the deduction of the type.
Anyway, the solution of the problem is simple: to make g++ happy, explicit the definition.
You know that a is an element of a_vector that is defined as a std::vector<A> const &, so you know that a is a A const &.
So, if you write the loop
for ( A const & a : a_vector )
{
// ....
}
there is no more needs to deduce the type of a and your code compile also with g++.
I am trying to implement an algorithm to process images with more than 256 bins.
The main issue to process histogram in such case comes from the impossibility to allocate more than 32 Kb as local tab in the GPU.
All the algorithms I found for 8 bits per pixel images use a fixed size tab locally.
The histogram is the first process in that tab then a barrier is up and at last an addition is made with the output vector.
I am working with IR image which has more than 32K bins of dynamic.
So I cannot allocate a fixed size tab inside the GPU.
My algorithm use an atomic_add in order to create directly the output histogram.
I am interfacing with OpenCV so, in order to manage the possible case of saturation my bins use floating points. Depending on the ability of the GPU to manage single or double precision.
OpenCV doesn't manage unsigned int, long, and unsigned long data type as matrix type.
I have an error... I do think this error is a kind of segmentation fault.
After several days I still have no idea what can be wrong.
Here is my code :
histogram.cl :
#pragma OPENCL EXTENSION cl_khr_fp64: enable
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics: enable
static void Atomic_Add_f64(__global double *val, double delta)
{
union {
double f;
ulong i;
} old;
union {
double f;
ulong i;
} new;
do {
old.f = *val;
new.f = old.f + delta;
}
while (atom_cmpxchg ( (volatile __global ulong *)val, old.i, new.i) != old.i);
}
static void Atomic_Add_f32(__global float *val, double delta)
{
union
{
float f;
uint i;
} old;
union
{
float f;
uint i;
} new;
do
{
old.f = *val;
new.f = old.f + delta;
}
while (atom_cmpxchg ( (volatile __global ulong *)val, old.i, new.i) != old.i);
}
__kernel void khist(
__global const uchar* _src,
const int src_steps,
const int src_offset,
const int rows,
const int cols,
__global uchar* _dst,
const int dst_steps,
const int dst_offset)
{
const int gid = get_global_id(0);
// printf("This message has been printed from the OpenCL kernel %d \n",gid);
if(gid < rows)
{
__global const _Sty* src = (__global const _Sty*)_src;
__global _Dty* dst = (__global _Dty*) _dst;
const int src_step1 = src_steps/sizeof(_Sty);
const int dst_step1 = dst_steps/sizeof(_Dty);
src += mad24(gid,src_step1,src_offset);
dst += mad24(gid,dst_step1,dst_offset);
_Dty one = (_Dty)1;
for(int c=0;c<cols;c++)
{
const _Rty idx = (_Rty)(*(src+c+src_offset));
ATOMIC_FUN(dst+idx+dst_offset,one);
}
}
}
The function Atomic_Add_f64 directly come from here and there
main.cpp
#include <opencv2/core.hpp>
#include <opencv2/core/ocl.hpp>
#include <fstream>
#include <sstream>
#include <chrono>
int main()
{
cv::Mat_<unsigned short> a(480,640);
cv::RNG rng(std::time(nullptr));
std::for_each(a.begin(),a.end(),[&](unsigned short& v){ v = rng.uniform(0,100);});
bool ret = false;
cv::String file_content;
{
std::ifstream file_stream("../test/histogram.cl");
std::ostringstream file_buf;
file_buf<<file_stream.rdbuf();
file_content = file_buf.str();
}
int output_flag = cv::ocl::Device::getDefault().doubleFPConfig() == 0 ? CV_32F : CV_64F;
cv::String atomic_fun = output_flag == CV_32F ? "Atomic_Add_f32" : "Atomic_Add_f64";
cv::ocl::ProgramSource source(file_content);
// std::cout<<source.source()<<std::endl;
cv::ocl::Kernel k;
cv::UMat src;
cv::UMat dst = cv::UMat::zeros(1,65536,output_flag);
a.copyTo(src);
atomic_fun = cv::format("-D _Sty=%s -D _Rty=%s -D _Dty=%s -D ATOMIC_FUN=%s",
cv::ocl::typeToStr(src.depth()),
cv::ocl::typeToStr(src.depth()), // this to manage case like a matrix of usigned short stored as a matrix of float.
cv::ocl::typeToStr(output_flag),
atomic_fun.c_str());
ret = k.create("khist",source,atomic_fun);
std::cout<<"check create : "<<ret<<std::endl;
k.args(cv::ocl::KernelArg::ReadOnly(src),cv::ocl::KernelArg::WriteOnlyNoSize(dst));
std::size_t sz = a.rows;
ret = k.run(1,&sz,nullptr,false);
std::cout<<"check "<<ret<<std::endl;
cv::Mat b;
dst.copyTo(b);
std::copy_n(b.ptr<double>(0),101,std::ostream_iterator<double>(std::cout," "));
std::cout<<std::endl;
return EXIT_SUCCESS;
}
Hello I arrived to fix it.
I don't really know where the issue come from.
But if I suppose the output as a pointer rather than a matrix it work.
The changes I made are these :
histogram.cl :
__kernel void khist(
__global const uchar* _src,
const int src_steps,
const int src_offset,
const int rows,
const int cols,
__global _Dty* _dst)
{
const int gid = get_global_id(0);
if(gid < rows)
{
__global const _Sty* src = (__global const _Sty*)_src;
__global _Dty* dst = _dst;
const int src_step1 = src_steps/sizeof(_Sty);
src += mad24(gid,src_step1,src_offset);
ulong one = 1;
for(int c=0;c<cols;c++)
{
const _Rty idx = (_Rty)(*(src+c+src_offset));
ATOMIC_FUN(dst+idx,one);
}
}
}
main.cpp
k.args(cv::ocl::KernelArg::ReadOnly(src),cv::ocl::KernelArg::PtrWriteOnly(dst));
The rest of the code is the same in the two files.
For me it work fine.
If someone know why it work when the ouput is declared as a pointer rather than a vector (matrix of one row) I am interested.
Nevertheless my issue is fix :).
Can any one help me desipher this error that I am getting while trying to open a port with a dll. I am getting an erro: "Access violation at address 0003D078" When I call SAAT_Open(myCharPtrOpen). Not sure if I am defininig the Handle correctly on unit UntRFIDAPI. Is the variable PHandle define correctly?
Here is my code:
procedure TForm5.Button1Click(Sender: TObject);
var
myString, myString2 : string;
myCharPtrInit: PChar;
myCharPtrOpen: PChar;
i : Integer;
Open, Init: Boolean;
begin
// Create a string of Char's
myString := '&hp';
// Point to the first character in the string
i := 1;
myCharPtrInit := Addr(myString[i]);
if SAAT_TCPInit(myCharPtrInit,'192.168.3.238',7086) = True then
begin
StatusBar1.Panels[0].Text := 'Initiated'; //ShowMessage('Initiated');
myString2 := 'hp';
myCharPtrOpen := Addr(myString2[i]);
if SAAT_Open(myCharPtrOpen) = True then StatusBar1.Panels[1].Text := 'Opened';
end;
end;
unit UntRFIDAPI;
INTERFACE
uses
SysUtils, Windows, Messages, Classes, Graphics, Controls, Dialogs,
StdCtrls, Forms, DBCtrls, DB, Grids, DBGrids,Mask, ExtCtrls,
Buttons, WinTypes;
var
A: String;
function SAAT_TCPInit(pHandle: Pointer; pHostName: String; nsocketPort: Integer):Boolean; stdcall;
function SAAT_Open(pHandle: Pointer):Boolean; stdcall;
function SAAT_Close(pHandle: Pointer):Boolean; stdcall;
implementation
function SAAT_TCPInit; external 'RFIDAPI.dll';
function SAAT_Open; external 'RFIDAPI.dll';
function SAAT_Close; external 'RFIDAPI.dll';
end.
Here is the API call:
1.1 Initialize Ethernet Port(TCP) connection
//TCP parameters initialization
//Functionality:import by parameter, initialize TCP to prepare for opening connection
//Parameters:
// pHandle for preserving the opening ports handl
// pHostName reader IP address, only effective under the ethernet communication
// nsocketPort network SOCKET port
//Returned value:true: Operation Succeeded, false Operation Failed
bool SAAT_TCPInit (void** pHandle,char *pHostName,int nsocketPort)
If the IP connecting to the reader is 192.168.0.238, port is 7086, then calling as follows:
HANDLE hp;
if (!SAAT_TCPInit(&hp, ”192.168.0.238”, 7086))
{
printf("reader initialization failed!\n");
return false;
}
As Rudy and David pointed out, your translation of the SAAT_TCPInit() function signature is wrong, and your use of a pointer handle with this API is wrong. They already explained why your code is wrong, so I won't repeat the reasons. They have some minor issues with their answers, though.
Your Delphi code should look more like this instead:
unit UntRFIDAPI;
interface
function SAAT_TCPInit(out pHandle: Pointer; pHostName: PAnsiChar; nsocketPort: Integer): Boolean; stdcall;
function SAAT_Open(pHandle: Pointer): Boolean; stdcall;
function SAAT_Close(pHandle: Pointer): Boolean; stdcall;
implementation
const
RFIDAPIDLL = 'RFIDAPI.dll';
function SAAT_TCPInit; external RFIDAPIDLL;
function SAAT_Open; external RFIDAPIDLL;
function SAAT_Close; external RFIDAPIDLL;
end.
procedure TForm5.Button1Click(Sender: TObject);
var
hp: Pointer;
begin
if SAAT_TCPInit(hp, '192.168.3.238', 7086) then
begin
StatusBar1.Panels[0].Text := 'Initiated';
if SAAT_Open(hp) then
StatusBar1.Panels[1].Text := 'Opened';
...
SAAT_Close(hp);
end;
end;
For reference, here is the content of the DLL's RFIDAPIEXPORT.h header file for C++:
/***********************************************************************
* Module: RFIDEXPORT.h
* Author:
* Modified:
* Purpose:
***********************************************************************/
#pragma once
#ifndef _RFIDEXPORT_H
#define _RFIDEXPORT_H
#ifdef RFIDAPI_EXPORTS
#define RFID_API __declspec( dllexport )
#else
#define RFID_API __declspec( dllimport )
#endif
extern "C"
{
bool RFID_API __stdcall SAAT_TCPInit(void** pHandle,char *pHostName,int nsocketPort);
bool RFID_API __stdcall SAAT_COMInit(void** pHandle,unsigned char nBusAddr,char *pComNum,int nBaud );
bool RFID_API __stdcall SAAT_USBInit(void** pHandle,unsigned char nBusAddr,char * pUSBNum,int nBaud );
bool RFID_API __stdcall SAAT_UDPInit(void** pHandle,char *pHostName,int nsocketPort);
bool RFID_API __stdcall SAAT_Open(void* pHandle);
bool RFID_API __stdcall SAAT_Close(void *pHandle);
bool RFID_API __stdcall SAAT_Reconnect(void *pHandle);
bool RFID_API __stdcall SAAT_HeartSend (void* pHandle);
bool RFID_API __stdcall SAAT_SysInfSet (void* pHandle ,unsigned char nType,unsigned char* pParm,int nLen);
bool RFID_API __stdcall SAAT_SysInfQuery (void* pHandle ,unsigned char nType, unsigned char *pPara, unsigned char *pLen);
bool RFID_API __stdcall SAAT_WorkModeSet (void* pHandle ,unsigned char nType);
bool RFID_API __stdcall SAAT_ParmOp (void* pHandle ,unsigned char nType, unsigned char nStartAddrr, unsigned char nLen, unsigned char *pData, unsigned char *pDataLen);
bool RFID_API __stdcall SAAT_RFParaSet (void* pHandle ,unsigned char nType, unsigned char nParaLen,unsigned char* pPara);
bool RFID_API __stdcall SAAT_RFParaQuery (void* pHandle ,unsigned char nType,unsigned char* pPara, unsigned char *pLen);
bool RFID_API __stdcall SAAT_CommunicatParaSet (void* pHandle ,unsigned char nType, unsigned char* pPara, unsigned char nLen);
bool RFID_API __stdcall SAAT_CommunicatParaQuery (void* pHandle ,unsigned char nType, unsigned char* pPara,unsigned char *pLen);
bool RFID_API __stdcall SAAT_NetParaSet (void* pHandle ,unsigned char nType, unsigned char* pPara, unsigned char nLen);
bool RFID_API __stdcall SAAT_NetParaQuery (void* pHandle ,int nType, unsigned char* pPara,unsigned char *pLen);
bool RFID_API __stdcall SAAT_TagOpParaSet(void* pHandle ,unsigned char nType, unsigned char *pPara,unsigned char nLen);
bool RFID_API __stdcall SAAT_TagOpParaQuery (void* pHandle ,unsigned char nType, unsigned char* pPara, unsigned char *pLen);
bool RFID_API __stdcall SAAT_ExtendBroadParaSet (void* pHandle ,unsigned char nType, unsigned char pSendChunnel);
bool RFID_API __stdcall SAAT_ExtendBroadParaQuery (void* pHandle ,unsigned char nType, char* pPara, unsigned char* pLen);
bool RFID_API __stdcall SAAT_TotalAntennaParmQuery (void* pHandle,unsigned char *szAntennaPara,unsigned char *pLen);
bool RFID_API __stdcall SAAT_AntennaParmQuery (void* pHandle,unsigned char nAntenna,unsigned char * pAntennaEnable,unsigned char *pAntennaPower,unsigned char *pAntennaQueryTime );
bool RFID_API __stdcall SAAT_AntennaParmSet(void* pHandle ,unsigned char *pPara,unsigned char nLen );
bool RFID_API __stdcall SAAT_SetAntennaPortEnable (void* pHandle,unsigned char nAntenna,unsigned char nEnable );
bool RFID_API __stdcall SAAT_SetAntennaPower (void* pHandle,unsigned char nAntenna,unsigned char nPower );
bool RFID_API __stdcall SAAT_SetAntennaTime (void* pHandle,unsigned char nAntenna,unsigned char nTime );
bool RFID_API __stdcall SAAT_PowerOff(void *pHandle);
bool RFID_API __stdcall SAAT_CarrierWaveOp(void* pHandle ,unsigned char nType, unsigned char nPort);
bool RFID_API __stdcall SAAT_IOOperate(void* pHandle,unsigned char nPort,unsigned char nState);
bool RFID_API __stdcall SAAT_IOStateQuery(void* pHandle,unsigned char *pState);
bool RFID_API __stdcall SAAT_Reboot (void* pHandle,unsigned char nMode);
bool RFID_API __stdcall SAAT_Reading_IOConfig (void* pHandle,unsigned char nConfigBit);
bool RFID_API __stdcall SAAT_Reading_IOQuery (void* pHandle,unsigned char* pConfigBit);
bool RFID_API __stdcall SAAT_IOPulseWidthSet (void* pHandle,unsigned char nIOPort,unsigned char nWidth);
bool RFID_API __stdcall SAAT_IOPulseWidthQuery (void* pHandle,unsigned char nIOPort,unsigned char* pWidth);
bool RFID_API __stdcall SAAT_6BTagSelect ( void* pHandle, unsigned char nType, unsigned char nStartAddr,
unsigned char nDataBite, unsigned char * Data );
bool RFID_API __stdcall SAAT_6BReadUIDCode (void *pHandle,unsigned char nAntenna,unsigned char nType);
int RFID_API __stdcall SAAT_6BRevUIDMsg (void *pHandle, unsigned char* nAntenna, unsigned char* pUIDData,
unsigned char* nUIDLen);
bool RFID_API __stdcall SAAT_6BReadUserData ( void *pHandle ,unsigned char nAntenna,unsigned char nType,unsigned char * pTagID,unsigned char nStartAddr,unsigned char nReadLen, unsigned char *pdata,unsigned char dataLen);
bool RFID_API __stdcall SAAT_6BWriteUserData (void* pHandle,
unsigned char nAntenna,
unsigned char nType,
unsigned char *pTagID,
unsigned char nStartAddr,
unsigned char *pValue,
unsigned char *pLen);
bool RFID_API __stdcall SAAT_6BTagLock (void* pHandle, unsigned char nAntenna, unsigned char nType,
unsigned char *pTagID, unsigned char nStartAddrr, unsigned char nLen);
bool RFID_API __stdcall SAAT_6BTagLockQuery (void* pHandle, unsigned char nAntenna,
unsigned char *pTagID, unsigned char nStartAddr, unsigned char nLen,unsigned char *pData,unsigned char nDataLen);
bool RFID_API __stdcall SAAT_6CTagSelect ( void *pHandle, unsigned char nBank ,unsigned short nStartAddr,unsigned char MaskBit,
unsigned char *Data ,unsigned char Datalength,unsigned char nSessionZone,
unsigned char nActiveFlag, unsigned char nCutFlag );
bool RFID_API __stdcall SAAT_6CReadEPCCode ( void *pHandle,unsigned char nAntenna, unsigned char nType,
unsigned int nTagCount);
int RFID_API __stdcall SAAT_6CRevEPCMsg (void *pHandle, unsigned char* nAntenna, unsigned char* pEPCData,
unsigned char* nEPCLen);
bool RFID_API __stdcall SAAT_6CReadTIDCode ( void *pHandle,unsigned char nAntenna, unsigned char nType, unsigned int nTagCount);
int RFID_API __stdcall SAAT_6CRevTIDMsg (void *pHandle, unsigned char* nAntenna, unsigned char* pTIDData, unsigned char* nTIDLen);
bool RFID_API __stdcall SAAT_6CWriteEPCCode ( void* pHandle,unsigned char nAntenna,unsigned char nType,
unsigned char *pAccessPWD, unsigned char *pWriteData,unsigned char nLen );
bool RFID_API __stdcall SAAT_6CReadUserData ( void* pHandle,
unsigned char nAntenna,
unsigned int StartAddr,
unsigned int nToReadLen,
unsigned int nWaitTime,
unsigned char * UserData,
unsigned int* pDataLen);
bool RFID_API __stdcall SAAT_6CWriteUserData (void* pHandle,
unsigned char nAntenna,
unsigned char nType,
unsigned char *pAccessPWD,
unsigned int nStartAddr,
unsigned int nWaitTime,
unsigned char *pWriteData,
unsigned int *pToWriteLen);
bool RFID_API __stdcall SAAT_6CWriteBankData (void* pHandle, unsigned char nAntenna, unsigned char nType, unsigned char *pAccessPWD,
unsigned char nBank, unsigned char *pWriteData, unsigned char nLen);
bool RFID_API __stdcall SAAT_6CClearBankData (void* pHandle, unsigned char nAntenna, unsigned char nType, unsigned char *pAccessPWD,
unsigned char nBank, unsigned char nStartAddr, unsigned char nLen);
bool RFID_API __stdcall SAAT_6CAccessPWDSet (void *pHandle, unsigned char nAntenna, unsigned char nType, unsigned char *pOrgPWD,
unsigned char *pNewPWD);
bool RFID_API __stdcall SAAT_6CDestroyPWDSet (void *pHandle, unsigned char nAntenna,unsigned char nType, unsigned char *pAccessPWD,
unsigned char *pDestroyPWD );
bool RFID_API __stdcall SAAT_6CTagLock (void *pHandle, unsigned char nAntenna, unsigned char *pAccessPWD, unsigned char nType,
unsigned char nBank);
bool RFID_API __stdcall SAAT_6CTagKill (void *pHandle, unsigned char nAntenna,unsigned char *pDestroyPWD,
unsigned char *pEPC, int nEPCLen);
bool RFID_API __stdcall SAAT_6CEASFlagSet (void *pHandle, unsigned char nAntenna, unsigned char nType,
unsigned char* pAccessPwd, int nEASFlag);
bool RFID_API __stdcall SAAT_6CEASMonitorEnable (void *pHandle, unsigned char nAntenna,unsigned char nSetEAS);
bool RFID_API __stdcall SAAT_Copyright(void** pHandle, char* copyright);
bool RFID_API __stdcall SAAT_SetLanguageType (void* pHandle,char* szType);
bool RFID_API __stdcall SAAT_GetErrorMessage(void *pHandle,char *szMsg, int nLen);
bool RFID_API __stdcall SAAT_GetErrorCode(void *pHandle,int *pCode);
bool RFID_API __stdcall SAAT_SysTest(void* pHandle ,unsigned char nType,unsigned char nAntenna, unsigned char *pTestParm, unsigned char nLen);
bool RFID_API __stdcall SAAT_RawSendData(void* pHandle , unsigned char *pSendData, unsigned char nLen);
bool RFID_API __stdcall SAAT_RawRevData(void* pHandle , unsigned char *pRecvData, unsigned char* pLen,int nWaitTime);
bool RFID_API __stdcall SAAT_RawSendAndRevData(void* pHandle ,
unsigned char *pSendData,
unsigned char nLen,
unsigned char *pRecvData,
unsigned char *pLen,
unsigned char nWaitTime);
bool RFID_API __stdcall SAAT_EnterTrans(void* pHandle ,unsigned char nType);
bool RFID_API __stdcall SAAT_ResetWifiBaund(void* pHandle);
};
#endif
And here is a link to the DLL's documentation:
API Calling Quick Start
SAAT-800 Series Reader.
bool SAAT_TCPInit(void** pHandle,char *pHostName,int nsocketPort)
This function yields a new handle which is of type void*. In Delphi that maps to Pointer, an untyped pointer. Because C only supports pass by value, in order to have the function pass a value out to the caller, the parameter is declared as a pointer to void*, that is void**.
The char* is an input parameter, a pointer to null terminated array of 8 bit characters. That maps to PAnsiChar. You absolutely must not use string for interop. It's a private Delphi type that is simply not valid for interop.
Since no calling convention is specified, we assume it to be cdecl.
The correct translation therefore is:
function SAAT_TCPInit(out Handle: Pointer; HostName: PAnsiChar;
SocketPort: Integer): Boolean; cdecl; external 'RFIDAPI.dll';
We've mapped the handle type, void* to Pointer. And the use of out introduces the extra level of indirection that is needed.
Call it like this:
var
Handle: Pointer;
....
if SAAT_TCPInit(Handle, '192.168.3.238', 7086) then
....
It is plausible that the functions in the DLL are actually stdcall, even though the C prototypes that you present do not specify that. If that is so, and only you can work that out, then you can change the calling convention accordingly. And in fact Remy has dug out the header file and shown that the functions are stdcall.
We cannot see the C declarations of the other function, but they look pretty simple. They both seem to accept the handle that was returned by the call to SAAT_TCPInit. So they should accept a parameter of type Pointer, passed by value. Presumably like this:
function SAAT_Open(Handle: Pointer): Boolean; cdecl; external 'RFIDAPI.dll';
And similarly for SAAT_Close.
In the interests of clarity it would probably be better to define a new type for this handle. Like so:
type
TSAATHandle = type Pointer;
Or if you'd rather:
type
TSAATHandle = type NativeUInt;
And obviously you'd then use this type rather than Pointer.
Your translation of the C headers is pretty much off. I don't have the prototypes for the other functions, but SAAT_TCPInit should be declared as:
function SAAT_TCPInit(var pHandle: THandle; pHostName: PAnsiChar; nSocketPort: Integer): ByteBool;
cdecl;
C doesn't know anything about Delphi strings, so don't translate C strings as Delphi's type string, since it is simply not binary compatible. char * should be translated as PAnsiChar. void** pHandle should be translated as var pHandle: THandle. And the calling convention is probably cdecl.
This assumes that the normal caling convention is used. If it is set to produce stdcall, then you'll have to declare that instead of cdecl.
I assume that is the main problem you have. Correct the translation and try again.
For more information about translating C headers, see my article Pitfalls of converting (Get it now, because the website may be offline for a while, I will be switching the provider).