#include "test.h"
#include <iostream.h>
#include <comdef.h>
#include <atlbase.h>
#pragma warning(disable:4146)
#import "C:\Program Files\Common Files\System\ado\msado15.dll" named_guids rename("EOF","adoEOF"), rename("BOF","adoBOF")
#pragma warning(default:4146)
//using namespace ADODB;char gettime()
{
_ConnectionPtr pConn("ADODB.Connection");
_RecordsetPtr pRs("ADODB.Recordset");
_CommandPtr pCommand;
pCommand.CreateInstance(__uuidof(Command));
// Cstring strConn;
pConn->Open("Provider=SQLOLEDB;Server=10.163.10.3;DataBase=master;UID=trace;PWD=traceaeclmis","","",adModeUnknown);
pConn->ConnectionTimeout=300; pCommand->ActiveConnection=pConn;
pCommand->CommandText="Select Convert(char(20),getdate(),120) AS sysTime";
pCommand->CommandType=adCmdText;
pCommand->CommandTimeout=300;
pCommand->Parameters->Refresh(); pRs=pCommand->Execute(NULL,NULL,adCmdUnknown);
_variant_t varValue=pRs->GetCollect("sysTime");
Cstring strValue=(char*)_bstr_t(varValue);
return strValue;
}以上代码是为了实现取SQL服务器时间,返回的一定要是字符串。我要封装在Win32 Dynamic-Link Library 里面供其他平台调用
大侠帮看看有什么问题,怎么这个函数无法调用到呢?
用VC++6.0 Depends 解析这个dll 没看到这个函数,肯定是有什么问题了。
#include <iostream.h>
#include <comdef.h>
#include <atlbase.h>
#pragma warning(disable:4146)
#import "C:\Program Files\Common Files\System\ado\msado15.dll" named_guids rename("EOF","adoEOF"), rename("BOF","adoBOF")
#pragma warning(default:4146)
//using namespace ADODB;char gettime()
{
_ConnectionPtr pConn("ADODB.Connection");
_RecordsetPtr pRs("ADODB.Recordset");
_CommandPtr pCommand;
pCommand.CreateInstance(__uuidof(Command));
// Cstring strConn;
pConn->Open("Provider=SQLOLEDB;Server=10.163.10.3;DataBase=master;UID=trace;PWD=traceaeclmis","","",adModeUnknown);
pConn->ConnectionTimeout=300; pCommand->ActiveConnection=pConn;
pCommand->CommandText="Select Convert(char(20),getdate(),120) AS sysTime";
pCommand->CommandType=adCmdText;
pCommand->CommandTimeout=300;
pCommand->Parameters->Refresh(); pRs=pCommand->Execute(NULL,NULL,adCmdUnknown);
_variant_t varValue=pRs->GetCollect("sysTime");
Cstring strValue=(char*)_bstr_t(varValue);
return strValue;
}以上代码是为了实现取SQL服务器时间,返回的一定要是字符串。我要封装在Win32 Dynamic-Link Library 里面供其他平台调用
大侠帮看看有什么问题,怎么这个函数无法调用到呢?
用VC++6.0 Depends 解析这个dll 没看到这个函数,肯定是有什么问题了。
我Mail: [email protected]
extern "C" _declspec(dllexport) _stdcall char gettime()
{
...
}
extern "C" _declspec(dllexport) _stdcall char* gettime()
{
...
}
e:\tddownload\test\debug\msado15.tlh(409) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
E:\TDdownload\test\test.cpp(14) : warning C4518: 'char ' : storage-class or type specifier(s) unexpected here; ignored是要引入什么名字空间吧??
extern "C" _declspec(dllexport) _stdcall char* gettime()
{
... // LZ不会把这个三个也带进去了吧
}
#12说的是 char ,不是char*,比较奇怪
DBTIME_API void GetTime(LPTSTR lpBuffer,int nBufferLength)
{
::CoInitialize(NULL);
_ConnectionPtr pConn;
pConn.CreateInstance(__uuidof(Connection));
_RecordsetPtr pRs;
pRs.CreateInstance(__uuidof(Recordset));
_CommandPtr pCommand;
pCommand.CreateInstance(__uuidof(Command)); pConn->Open(_bstr_t("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=test;Data Source=(local)"),"","",adModeUnknown);
//pConn->ConnectionTimeout=(long)300; pCommand->ActiveConnection=pConn;
pCommand->CommandText=_bstr_t("Select Convert(varchar(20),getdate(),120) AS sysTime");
pCommand->CommandType=adCmdText;
//pCommand->CommandTimeout=(long)300;
pCommand->Parameters->Refresh(); pRs=pCommand->Execute(NULL,NULL,adCmdUnknown);
_variant_t varValue=pRs->GetCollect("sysTime");
_bstr_t bstrValue=varValue.bstrVal; LPTSTR pszDestText, pszDestEnd ;
size_t cchRemaining = 0;
StringCchPrintfEx(lpBuffer,
nBufferLength,
&pszDestEnd,
&cchRemaining,
STRSAFE_FILL_BEHIND_NULL,
_T("%s"),
(LPCTSTR)bstrValue
);
::CoUninitialize();
return;}DBTime.hDBTIME_API void GetTime(LPTSTR lpBuffer,int nBufferLength);调用DBTime.dll 中GetTime#include "..\DBTime\DBTime.h"
#pragma comment(lib, "D:\\projects2008\\VCTrainning\\Debug\\DBTime.lib")DWORD DLLTesting()
{
TCHAR lpDBTime[100];
ZeroMemory(lpDBTime, sizeof(TCHAR) * 100);
GetTime(lpDBTime, 100);
TRACE(_T("GetTime=%s\r\n"), lpDBTime);
return 0;
}
这个函数在vb里面调用的时候怎么搞?
能不能改改,让这个函数没有参数,在vb 里面直接调用就完了,最多分配内存。
我自己再试试吧。
编译出错:
e:\tddownload\timeget\gettime\gettime.h(1) : error C2144: syntax error : missing ';' before type 'void'
e:\tddownload\timeget\gettime\gettime.h(1) : error C2501: 'DBTIME_API' : missing storage-class or type specifiers
e:\tddownload\timeget\gettime\gettime.h(1) : fatal error C1004: unexpected end of file found都指向你的头文件DBTime.h
好多Warning & Error:
test.cpp
e:\tddownload\test\test.h(1) : warning C4185: ignoring unknown #import attribute 'no_namespaces'
e:\tddownload\test\debug\msado15.tlh(409) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
E:\TDdownload\test\test.cpp(14) : warning C4518: 'char ' : storage-class or type specifier(s) unexpected here; ignored
E:\TDdownload\test\test.cpp(14) : warning C4230: anachronism used : modifiers/qualifiers interspersed, qualifier ignored
E:\TDdownload\test\test.cpp(15) : error C2165: 'left-side modifier' : cannot modify pointers to data
E:\TDdownload\test\test.cpp(15) : error C2501: 'gettime' : missing storage-class or type specifiers
E:\TDdownload\test\test.cpp(15) : error C2556: 'int *__cdecl gettime(void)' : overloaded function differs only by return type from 'char *__cdecl gettime(void)'
e:\tddownload\test\test.h(4) : see declaration of 'gettime'
E:\TDdownload\test\test.cpp(16) : error C2065: '_ConnectionPtr' : undeclared identifier
E:\TDdownload\test\test.cpp(16) : error C2146: syntax error : missing ';' before identifier 'pConn'
E:\TDdownload\test\test.cpp(16) : error C2065: 'pConn' : undeclared identifier
E:\TDdownload\test\test.cpp(17) : error C2065: '_RecordsetPtr' : undeclared identifier
E:\TDdownload\test\test.cpp(17) : error C2146: syntax error : missing ';' before identifier 'pRs'
E:\TDdownload\test\test.cpp(17) : error C2065: 'pRs' : undeclared identifier
E:\TDdownload\test\test.cpp(18) : error C2065: '_CommandPtr' : undeclared identifier
E:\TDdownload\test\test.cpp(18) : error C2146: syntax error : missing ';' before identifier 'pCommand'
E:\TDdownload\test\test.cpp(18) : error C2065: 'pCommand' : undeclared identifier
E:\TDdownload\test\test.cpp(19) : error C2228: left of '.CreateInstance' must have class/struct/union type
E:\TDdownload\test\test.cpp(19) : error C2065: 'Command' : undeclared identifier
E:\TDdownload\test\test.cpp(22) : error C2227: left of '->Open' must point to class/struct/union
E:\TDdownload\test\test.cpp(22) : error C2065: 'adModeUnknown' : undeclared identifier
E:\TDdownload\test\test.cpp(24) : error C2227: left of '->ConnectionTimeout' must point to class/struct/union
E:\TDdownload\test\test.cpp(26) : error C2227: left of '->ActiveConnection' must point to class/struct/union
E:\TDdownload\test\test.cpp(27) : error C2227: left of '->CommandText' must point to class/struct/union
E:\TDdownload\test\test.cpp(28) : error C2227: left of '->CommandType' must point to class/struct/union
E:\TDdownload\test\test.cpp(28) : error C2065: 'adCmdText' : undeclared identifier
E:\TDdownload\test\test.cpp(29) : error C2227: left of '->CommandTimeout' must point to class/struct/union
E:\TDdownload\test\test.cpp(30) : error C2227: left of '->Parameters' must point to class/struct/union
E:\TDdownload\test\test.cpp(30) : error C2227: left of '->Refresh' must point to class/struct/union
E:\TDdownload\test\test.cpp(32) : error C2227: left of '->Execute' must point to class/struct/union
E:\TDdownload\test\test.cpp(32) : error C2065: 'adCmdUnknown' : undeclared identifier
E:\TDdownload\test\test.cpp(33) : error C2227: left of '->GetCollect' must point to class/struct/union
E:\TDdownload\test\test.cpp(34) : error C2065: 'CString' : undeclared identifier
E:\TDdownload\test\test.cpp(34) : error C2146: syntax error : missing ';' before identifier 'strValue'
E:\TDdownload\test\test.cpp(34) : error C2065: 'strValue' : undeclared identifier
E:\TDdownload\test\test.cpp(34) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class _bstr_t' (or there is no acceptable conversion)
Ö´ÐÐ cl.exe ʱ³ö´í.test.dll - 1 error(s), 0 warning(s)
改起来很容易,不过我建议你做成ATL组件形式
如果改成COM(ATL)组件
这样在VB中可以这样使用set tm = createobject("DBTimeLib.DBTime")
str = tm.GetTime()
msgbox str这就是VB的调用方式,而且适用性更好一些如果要从VB中调用普通的DLL,那么就是多几行代码就看你的要求了
如果有标准dll 的话就更好了,不论什么平台都可以使用。
主要的源代码如下:
stdafx.h
C/C++ code
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//#pragma once#include "targetver.h"#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit#include <atlbase.h>
#include <atlstr.h>// TODO: reference additional headers your program requires here
#include <strsafe.h>
#import "d:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF") DBTime.h
C/C++ code
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the DBTIME_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// DBTIME_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef DBTIME_EXPORTS
#define DBTIME_API __declspec(dllexport)
#else
#define DBTIME_API __declspec(dllimport)
#endif// This class is exported from the DBTime.dll
class DBTIME_API CDBTime {
public:
CDBTime(void);
// TODO: add your methods here.
};extern DBTIME_API int nDBTime;DBTIME_API int fnDBTime(void);DBTIME_API void GetTime(LPTSTR lpBuffer,int nBufferLength);
DBTIME_API LPTSTR GetTimeEx();DBTime.cpp C/C++ code
// DBTime.cpp : Defines the exported functions for the DLL application.
//#include "stdafx.h"
#include "DBTime.h"
// This is an example of an exported variable
DBTIME_API int nDBTime=0;// This is an example of an exported function.
DBTIME_API int fnDBTime(void)
{
return 42;
}// This is an example of an exported function.
DBTIME_API void GetTime(LPTSTR lpBuffer,int nBufferLength)
{
::CoInitialize(NULL);
_ConnectionPtr pConn;
pConn.CreateInstance(__uuidof(Connection));
_RecordsetPtr pRs;
pRs.CreateInstance(__uuidof(Recordset));
_CommandPtr pCommand;
pCommand.CreateInstance(__uuidof(Command)); pConn->Open(_bstr_t("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;User ID=sa;Initial Catalog=test;Data Source=(local)"),"","",adModeUnknown);
//pConn->ConnectionTimeout=(long)300; pCommand->ActiveConnection=pConn;
pCommand->CommandText=_bstr_t("Select Convert(varchar(20),getdate(),120) AS sysTime");
pCommand->CommandType=adCmdText;
//pCommand->CommandTimeout=(long)300;
pCommand->Parameters->Refresh(); pRs=pCommand->Execute(NULL,NULL,adCmdUnknown);
_variant_t varValue=pRs->GetCollect("sysTime");
_bstr_t bstrValue=varValue.bstrVal; LPTSTR pszDestText, pszDestEnd ;
size_t cchRemaining = 0;
StringCchPrintfEx(lpBuffer,
nBufferLength,
&pszDestEnd,
&cchRemaining,
STRSAFE_FILL_BEHIND_NULL,
_T("%s"),
(LPCTSTR)bstrValue
);
::CoUninitialize();
return;}// This is an example of an exported function.
DBTIME_API LPTSTR GetTimeEx()
{
::CoInitialize(NULL);
_ConnectionPtr pConn;
pConn.CreateInstance(__uuidof(Connection));
_RecordsetPtr pRs;
pRs.CreateInstance(__uuidof(Recordset));
_CommandPtr pCommand;
pCommand.CreateInstance(__uuidof(Command)); pConn->Open(_bstr_t("Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=test;Data Source=(local)"),"","",adModeUnknown);
//pConn->ConnectionTimeout=(long)300; pCommand->ActiveConnection=pConn;
pCommand->CommandText=_bstr_t("Select Convert(varchar(20),getdate(),120) AS sysTime");
pCommand->CommandType=adCmdText;
//pCommand->CommandTimeout=(long)300;
pCommand->Parameters->Refresh(); pRs=pCommand->Execute(NULL,NULL,adCmdUnknown);
_variant_t varValue=pRs->GetCollect("sysTime");
_bstr_t bstrValue=varValue.bstrVal; LPTSTR lpBuffer = new TCHAR[100];
LPTSTR pszDestEnd ;
size_t cchRemaining = 0;
StringCchPrintfEx(lpBuffer,
100,
&pszDestEnd,
&cchRemaining,
STRSAFE_FILL_BEHIND_NULL,
_T("%s"),
(LPCTSTR)bstrValue
);
::CoUninitialize();
return lpBuffer;}
// This is the constructor of a class that has been exported.
// see DBTime.h for the class definition
CDBTime::CDBTime()
{
return;
}这个DLL里面有两个API,GetTime()和GetTimeEx(),生成的DLL名字为DBTime.dll,导出的声明都在DBTime.h中,调试的时候需要用到这个头文件
我不需要跨平台调用,都是windows,只是98 上用而已。
但是这个dll 做出来到时候是给98系统或者2000系统用的
没什么关系吧?
第二,怎样在规则dll中实现返回字符串
第三,这个dll是否能够为vb或者类似vb的应用开发环境所调用
第四,怎样的字符串能被vb使用第二个问题是关键首先,楼主返回char,是错误的,因为这仅仅是一个单字节的字符,不是一个字符串。
常规的函数或者API,返回字符串。有基本的两种第一个,是返回字符串的指针char *
这种返回指针的方式,要考虑字符串的生命期范围的问题。所以没有经验的人,要谨慎使用第二个,是返回CString,或者string这样类对象。
这个方式的好处是这些类对象内部可以维护内存释放的问题。比较省心,不好处是必须依赖MFC,或者STL。至于,其他BSTR,variant,暂时不讨论,因为我们的dll,不是com组件和接口。仅仅是API的封装。先写到这里,下回继续