Delphi如何调用C++的DLL
delphi吧
全部回复
仅看楼主
level 3
vopr 楼主
Delphi如何调用C++的DLL
源代码如下:
Pipe.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include
#ifdef _WIN32
#include
#else
#include
#endif
#include "base2.h"
#include "pipe.h"
inline void ParsePath(char *szDir, char *szFile, const char *szPath) {
char *lpSeperator;
strcpy(szDir, szPath);
lpSeperator = strrchr(szDir, PATH_SEPERATOR);
if (lpSeperator == NULL) {
szDir[0] = '\0';
strcpy(szFile, szPath);
} else {
*lpSeperator = '\0';
strcpy(szFile, lpSeperator + 1);
}
}
#ifdef _WIN32
#ifdef PIPE_DLL
extern "C" __dec
lsp
ec(dllexport) VOID WINAPI PipeOpen(PipeStruct *lppipe, LPCSTR szProcFile);
extern "C" __declspec(dllexport) VOID WINAPI PipeClose(PipeStruct *lppipe);
extern "C" __declspec(dllexport) LPSTR WINAPI PipeLineInput(PipeStruct *lppipe);
extern "C" __declspec(dllexport) VOID WINAPI PipeLineOutput(PipeStruct *lppipe, LPCSTR szLineStr);
VOID WINAPI PipeOpen(PipeStruct *lppipe, LPCSTR szProcFile) {
lppipe->Open(szProcFile);
}
VOID WINAPI PipeClose(PipeStruct *lppipe) {
lppipe->Close();
}
LPSTR WINAPI PipeLineInput(PipeStruct *lppipe) {
static char szBuffer[LINE_INPUT_MAX_CHAR];
if (lppipe->LineInput(szBuffer)) {
return szBuffer;
} else {
return NULL;
}
}
VOID WINAPI PipeLineOutput(PipeStruct *lppipe, LPCSTR szLineStr) {
lppipe->LineOutput(szLineStr);
}
#endif
void PipeStruct::Open(const char *szProcFile) {
DWORD dwMode;
HANDLE hStdinRead, hStdinWrite, hStdoutRead, hStdoutWrite;
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
char szFileDir[PATH_MAX_CHAR], szFileName[PATH_MAX_CHAR], szCurDir[PATH_MAX_CHAR];
if (szProcFile == NULL) {
hInput = GetStdHandle(STD_INPUT_HANDLE);
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
bConsole = GetConsoleMode(hInput, &dwMode);
} else {
GetCurrentDirectory(PATH_MAX_CHAR, szCurDir);
ParsePath(szFileDir, szFileName, szProcFile);
SetCurrentDirectory(szFileDir);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
CreatePipe(&hStdinRead, &hStdinWrite, &sa, 0);
CreatePipe(&hStdoutRead, &hStdoutWrite, &sa, 0);
si.cb = sizeof(STARTUPINFO);
si.lpReserved = si.lpDesktop = si.lpTitle = NULL;
si.dwFlags = STARTF_USESTDHANDLES;
si.cbReserved2 = 0;
si.lpReserved2 = NULL;
si.hStdInput = hStdinRead;
si.hStdOutput = hStdoutWrite;
si.hStdError = hStdoutWrite;
CreateProcess(NULL, (LPSTR) szFileName, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hStdinRead);
CloseHandle(hStdoutWrite);
hInput = hStdoutRead;
hOutput = hStdinWrite;
bConsole = FALSE;
SetCurrentDirectory(szCurDir);
}
if (bConsole) {

2012年05月20日 05点05分 1
level 3
vopr 楼主
SetConsoleMode(hInput, dwMode & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
FlushConsoleInputBuffer(hInput);
}
nBytesLeft = 0;
nReadEnd = 0;
}
void PipeStruct::Close(void) const {
CloseHandle(hInput);
CloseHandle(hOutput);
}
void PipeStruct::ReadInput(void) {
DWORD dwBytes;
ReadFile(hInput, szBuffer + nReadEnd, LINE_INPUT_MAX_CHAR - nReadEnd, &dwBytes, NULL);
nReadEnd += dwBytes;
if (nBytesLeft > 0) {
nBytesLeft -= dwBytes;
}
}
bool PipeStruct::CheckInput(void) {
DWORD dwEvents, dwBytes;
if (bConsole) { // a tty, or an un-redirected handle
GetNumberOfConsoleInputEvents(hInput, &dwEvents);
return dwEvents > 1;
} else if (nBytesLeft > 0) { // a pipe with remainder data
return true;
} else if (PeekNamedPipe(hInput, NULL, 0, NULL, &dwBytes, NULL)) { // a pipe without remainder data
nBytesLeft = dwBytes;
return nBytesLeft > 0;
} else { // a file, always true
return true;
}
}
void PipeStruct::LineOutput(const char *szLineStr) const {
DWORD dwBytes;
int nStrLen;
char szWriteBuffer[LINE_INPUT_MAX_CHAR];
nStrLen = strlen(szLineStr);
memcpy(szWriteBuffer, szLineStr, nStrLen);
szWriteBuffer[nStrLen] = '\r';
szWriteBuffer[nStrLen + 1] = '\n';
WriteFile(hOutput, szWriteBuffer, nStrLen + 2, &dwBytes, NULL);
}
#else
#include
#include
#include
#include
#include
void PipeStruct::Open(const char *szProcFile) {
int nStdinPipe[2], nStdoutPipe[2];
char szFileDir[PATH_MAX_CHAR], szFileName[PATH_MAX_CHAR];
if (szProcFile == NULL) {
nInput = STDIN_FILENO;
nOutput = STDOUT_FILENO;
} else {
pipe(nStdinPipe);
pipe(nStdoutPipe);
if (fork() == 0) {
close(nStdinPipe[1]);
close(nStdoutPipe[0]);
dup2(nStdinPipe[0], STDIN_FILENO);
close(nStdinPipe[0]);
dup2(nStdoutPipe[1], STDOUT_FILENO);
dup2(nStdoutPipe[1], STDERR_FILENO);
close(nStdoutPipe[1]);
ParsePath(szFileDir, szFileName, szProcFile);
chdir(szFileDir);
nice(20);
execl(szFileName, szFileName, NULL);
exit(EXIT_FAILURE);
}
close(nStdinPipe[0]);
close(nStdoutPipe[1]);
nInput = nStdoutPipe[0];
nOutput = nStdinPipe[1];
}
nReadEnd = 0;
}
void PipeStruct::Close(void) const {
close(nInput);
close(nOutput);
}
void PipeStruct::ReadInput(void) {
nReadEnd += read(nInput, szBuffer + nReadEnd, LINE_INPUT_MAX_CHAR - nReadEnd);
}
bool PipeStruct::CheckInput(void) {
fd_set set;
timeval tv;
int val;
FD_ZERO(&set);
FD_SET(nInput, &set);
tv.tv_sec = 0;
tv.tv_usec = 0;
val = select(nInput + 1, &set, NULL, NULL, &tv);
return (val > 0 && FD_ISSET(nInput, &set) > 0);
}
void PipeStruct::LineOutput(const char *szLineStr) const {
int nStrLen;
char szWriteBuffer[LINE_INPUT_MAX_CHAR];
nStrLen = strlen(szLineStr);
memcpy(szWriteBuffer, szLineStr, nStrLen);
szWriteBuffer[nStrLen] = '\n';
write(nOutput, szWriteBuffer, nStrLen + 1);
}
#endif
bool PipeStruct::GetBuffer(char *szLineStr) {

2012年05月20日 05点05分 2
level 3
vopr 楼主
char *lpFeedEnd;
int nFeedEnd;
lpFeedEnd = (char *) memchr(szBuffer, '\n', nReadEnd);
if (lpFeedEnd == NULL) {
return false;
} else {
nFeedEnd = lpFeedEnd - szBuffer;
memcpy(szLineStr, szBuffer, nFeedEnd);
szLineStr[nFeedEnd] = '\0';
nFeedEnd ++;
nReadEnd -= nFeedEnd;
memcpy(szBuffer, szBuffer + nFeedEnd, nReadEnd);
lpFeedEnd = (char *) strchr(szLineStr, '\r');
if (lpFeedEnd != NULL) {
*lpFeedEnd = '\0';
}
return true;
}
}
bool PipeStruct::LineInput(char *szLineStr) {
if (GetBuffer(szLineStr)) {
return true;
} else if (CheckInput()) {
ReadInput();
if (GetBuffer(szLineStr)) {
return true;
} else if (nReadEnd == LINE_INPUT_MAX_CHAR) {
memcpy(szLineStr, szBuffer, LINE_INPUT_MAX_CHAR - 1);
szLineStr[LINE_INPUT_MAX_CHAR - 1] = '\0';
szBuffer[0] = szBuffer[LINE_INPUT_MAX_CHAR - 1];
nReadEnd = 1;
return true;
} else {
return false;
}
} else {
return false;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Pipe.h
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#include
#endif
#include "base.h"
#ifndef PIPE_H
#define PIPE_H
const int LINE_INPUT_MAX_CHAR = 4096;
struct PipeStruct {
#ifdef _WIN32
HANDLE hInput, hOutput;
BOOL bConsole;
int nBytesLeft;
#else
int nInput, nOutput;
#endif
int nReadEnd;
char szBuffer[LINE_INPUT_MAX_CHAR];
void Open(const char *szExecFile = NULL);
void Close(void) const;
void ReadInput(void);
bool CheckInput(void);
bool GetBuffer(char *szLineStr);
bool LineInput(char *szLineStr);
void LineOutput(const char *szLineStr) const;
}; // pipe
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
base.h
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include
#include
#ifndef BASE_H
#define BASE_H
#ifdef _MSC_VER
typedef signed __int64 int64_t; // ll
typedef unsigned __int64 uint64_t; // qw
typedef signed __int32 int32_t; // l
typedef unsigned __int32 uint32_t; // dw
typedef signed __int16 int16_t; // s
typedef unsigned __int16 uint16_t; // w
typedef signed __int8 int8_t; // c
typedef unsigned __int8 uint8_t; // uc
#define FORMAT_I64 "I64"
#else
#include
#define FORMAT_I64 "ll"
#endif
#define __ASSERT(a) assert(a)
#define __ASSERT_BOUND(a, b, c) assert((a) <= (b) && (b) <= (c))
#define __ASSERT_BOUND_2(a, b, c, d) assert((a) <= (b) && (b) <= (c) && (c) <= (d))
inline bool EQV(bool bArg1, bool bArg2) {
return bArg1 ? bArg2 : !bArg2;
}
inline bool XOR(bool bArg1, bool bArg2) {
return bArg1 ? !bArg2 : bArg2;

2012年05月20日 05点05分 3
level 3
vopr 楼主
}
template inline T MIN(T Arg1, T Arg2) {
return Arg1 < Arg2 ? Arg1 : Arg2;
}
template inline T MAX(T Arg1, T Arg2) {
return Arg1 > Arg2 ? Arg1 : Arg2;
}
template inline T ABS(T Arg) {
return Arg < 0 ? -Arg : Arg;
}
template inline T SQR(T Arg) {
return Arg * Arg;
}
template inline void SWAP(T &Arg1, T &Arg2) {
T Temp;
Temp = Arg1;
Arg1 = Arg2;
Arg2 = Temp;
}
inline int PopCnt8(uint8_t uc) {
int n;
n = ((uc >> 1) & 0x55) + (uc & 0x55);
n = ((n >> 2) & 0x33) + (n & 0x33);
return (n >> 4) + (n & 0x0f);
}
inline int PopCnt16(uint16_t w) {
int n;
n = ((w >> 1) & 0x5555) + (w & 0x5555);
n = ((n >> 2) & 0x3333) + (n & 0x3333);
n = ((n >> 4) & 0x0f0f) + (n & 0x0f0f);
return (n >> 8) + (n & 0x00ff);
}
inline int PopCnt32(uint32_t dw) {
int n;
n = ((dw >> 1) & 0x55555555) + (dw & 0x55555555);
n = ((n >> 2) & 0x33333333) + (n & 0x33333333);
n = ((n >> 4) & 0x0f0f0f0f) + (n & 0x0f0f0f0f);
n = ((n >> 8) & 0x00ff00ff) + (n & 0x00ff00ff);
return (n >> 16) + (n & 0x0000ffff);
}
inline int64_t GetTime() {
timeb tb;
ftime(&tb);
return (int64_t) tb.time * 1000 + tb.millitm;
}
template class Stack {
int nSize, nTop;
T *Elements;
public:
Stack(int nSize_) {
nSize = nSize_;
nTop = 0;
Elements = new T[nSize];
}
~Stack(void) {
delete[] Elements;
}
bool Push(T o) {
if (nTop == nSize) {
return false;
}
Elements[nTop] = o;
nTop ++;
return true;
}
bool Pop(T &o) {
if (nTop == 0) {
return false;
}
nTop --;
o = Elements[nTop];
return true;
}
};
template class Queue {
int nSize, nHead, nTail;
T *Elements;
public:
Queue(int nSize_) {
nSize = nSize_;
nHead = nTail = 0;
Elements = new T[nSize];
}
~Queue(void) {
delete[] Elements;
}
bool Offer(T o) {
int nNewTail = (nTail + 1) % nSize;
if (nNewTail == nHead) {
return false;
}
Elements[nTail] = o;
nTail = nNewTail;
return true;
}
bool Poll(T &o) {
if (nTail == nHead) {
return false;
}
int nOldHead = nHead;
nHead = (nHead + 1) % nSize;
o = Elements[nOldHead];
return true;
}
};
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
base2.h
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#include
#else
#include
#include
#include
#endif
#include
#include "base.h"
#ifndef BASE2_H
#define BASE2_H
const int PATH_MAX_CHAR = 1024;
#ifdef _WIN32
inline void Idle(void) {
Sleep(1);
}
const int PATH_SEPERATOR = '\\';
inline bool AbsolutePath(const char *sz) {
return sz[0] == '\\' || (((sz[0] >= 'A' && sz[0] <= 'Z') || (sz[0] >= 'a' && sz[0] <= 'z')) && sz[1] == ':');
}
inline void GetSelfExe(char *szDst) {
GetModuleFileName(NULL, szDst, PATH_MAX_CHAR);
}
inline void StartThread(void *ThreadEntry(void *), void *lpParameter) {
DWORD dwThreadId;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadEntry, (LPVOID) lpParameter, 0, &dwThreadId);
}
#else
inline void Idle(void) {
usleep(1000);
}
const int PATH_SEPERATOR = '/';
inline bool AbsolutePath(const char *sz) {
return sz[0] == '/' || (sz[0] == '~' && sz[1] == '/');
}
inline void GetSelfExe(char *szDst) {
readlink("/proc/self/exe", szDst, PATH_MAX_CHAR);
}
inline void StartThread(void *ThreadEntry(void *), void *lpParameter) {
pthread_t pthread;
pthread_attr_t pthread_attr;
pthread_attr_init(&pthread_attr);
pthread_attr_setscope(&pthread_attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&pthread, &pthread_attr, ThreadEntry, lpParameter);
}
#endif
inline void LocatePath(char *szDst, const char *szSrc) {
char *lpSeperator;
if (AbsolutePath(szSrc)) {
strcpy(szDst, szSrc);
} else {
GetSelfExe(szDst);
lpSeperator = strrchr(szDst, PATH_SEPERATOR);
if (lpSeperator == NULL) {
strcpy(szDst, szSrc);
} else {
strcpy(lpSeperator + 1, szSrc);
}
}
}
#endif
2012年05月20日 05点05分 4
level 5
这个和其它的调用应该没有什么区别:
给你举个例子:
比如,我想调用DLL中的函数
PipeOpen(ParamA,ParamB);
=======================================================
Procedure TForm1.ExecFunc1;
var
HInst : THandle;
FPointer : TFarProc;
begin
HInst := LoadLibrary('YourDLL');
if HInst > 0 then begin
Try
FPointer := GetProcAddress(HInst,'PipeOpen');
IF FPointer <> nil then begin
PipeOpen(ParamA,ParamB) ; //前面要定议一下 StdCall
end;
Finally
FreeLibrary(HInst);
End;
end;
end;
===========================================================
这个是通用的思路。
你自己再琢磨一下。

2012年05月23日 01点05分 5
1