我正在尝试从C ++调用C#库。这是进行第一次调用的函数:
CapsReport::CapsReport(const CCOMString& reportFileName, CCDatabase* pDatabase)
: m_pDatabase(pDatabase), m_pReportServer(__uuidof(ReportServer))
{
::CoInitialize(NULL);
SetReportName(reportFileName);
// public void Load(string DSNname, string userName, string password, string reportFileName)
BSTR dsnBstr = pDatabase->DataSource().GetManagedBstr();
BSTR userBstr = pDatabase->UserName().GetManagedBstr();
BSTR passwordBstr = pDatabase->Password().GetManagedBstr();
BSTR reportNameBstr = ::SysAllocString(reportFileName);
m_pReportServer->Load(dsnBstr, userBstr, passwordBstr, reportNameBstr);
::SysFreeString(reportNameBstr);
}
在调用Load()方法时,GetManagedBstr()返回的所有三个BSTR都包含密码。我正试图找出原因。
DataSource(),UserName()和Password()都返回CCOMString类型的对象:
CCOMString UserName() { return m_User; };
CCOMString Password() { return m_Pwd; };
CCOMString DataSource() { return m_DSN; };
我不想每次想将CCOMString传递到C#库时都必须调用:: SysAllocString()和:: SysFreeString(),所以我向初始化为NULL的CCOMString类添加了一个私有BSTR成员。 。在析构函数中,我检查该成员是否为null。如果不是,我调用:: SysFreeString()并将其设置为NULL。
GetManagedBstr()方法使用CCOMString的现有成员函数AllocSysString()。首先,这里是GetManagedBstr():
BSTR CCOMString::GetManagedBstr()
{
m_bstr = AllocSysString();
return m_bstr;
}
现在,这是AllocSysString():
BSTR CCOMString::AllocSysString() const
{
#ifndef _UNICODE
int nLen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)m_pszString, GetLength(), NULL, NULL);
BSTR bstr = ::SysAllocString(NULL, nLen+1);
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)m_pszString, GetLength(), bstr, nLen);
#else
int nLen = _tcslen(m_pszString);
//BSTR bstr = ::SysAllocStringLen(NULL, nLen);
BSTR bstr = ::SysAllocString(m_pszString);
// _tcscpy_s(bstr, nLen, m_pszString);
#endif
return bstr;
}
m_pszString仅仅是由CCOMString包装的普通普通C ++字符串。
BSTR对象是一个指针。不知何故,所有三个BSTR对象最终都指向相同的内存位置,即使它们本来应该来自不同的CCOMString对象也是如此。这是怎么回事?