我的函数、简单的写一下
extern "C" int Trans( const char *Sentence1, CString& Sentence2)
{
CString myString="";
.....
Sentence2 = myString;
return 1; }在这里 Sentence2 = myString;总是出错、为什么?
CString myString="";把myString 变为全局变量也不行。
extern "C" int Trans( const char *Sentence1, CString& Sentence2)
{
CString myString="";
.....
Sentence2 = myString;
return 1; }在这里 Sentence2 = myString;总是出错、为什么?
CString myString="";把myString 变为全局变量也不行。
我的函数是Dll函数。
NTDLL! 7c9acd80()
NTDLL! 7c9a0af8()
KERNEL32! 7c85e7af()
_CrtIsValidHeapPointer(const void * 0x006118e8 int * _afxInitData) line 1697
_free_dbg_lk(void * 0x006118e8 int * _afxInitData, int 0x00000001) line 1044 + 9 bytes
_free_dbg(void * 0x006118e8 int * _afxInitData, int 0x00000001) line 1001 + 13 bytes
operator delete(void * 0x006118e8 int * _afxInitData) line 351 + 11 bytes
CString::FreeData() line 146 + 15 bytes
CString::Release() line 157
CString::AllocBeforeWrite(int 0x00000003) line 200
CString::AssignCopy(int 0x00000003, const char * 0x01087a1c) line 315
CString::operator=(const char * 0x01087a1c) line 346
堆栈信息
主程序调用函数int ReadFile(const TCHAR *filename )
{
.......
CString strMorph="";
Trans( m_strGenbun, strMorph);
}
{
CString str1= "这是初值";
Function(str1);
AfxMessageBox(str1);
}void CCStringDlg::Function(CString &str)
{
CString ss = "AAAAAAA";
str = ss;}
AFX_MANAGE_STATE(AfxGetStaticModuleState()) ;
如下:
///////////////////////////////////////////////////////////////////
extern "C" int Trans( const char *Sentence1, CString& Sentence2)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()) ;
CString myString="";
.....
Sentence2 = myString;
return 1; }
CString::AllocBuffer(int nLen);
问题就出在Sentence2上
但是调用它的时候已经赋值为""了。为什么呢?多谢各位指点!
用 char * 传回字符串、要定义一个全局变量、每次字符串大小不一定、大的话就太浪费了。
extern "C" int Trans( const char *Sentence1, char** Sentence2)
{
CString myString="";
.....
*Sentence2 = new char [myString.GetLength()];
strcpy (*Senetence2, myString);
return 1; }
然后在函数调用后把值赋给一个CString对象。对了,记得delete。
{
CString myString="";
.....
Sentence2 = (char*)GlobalAlloc(GHND,myString.GetLength());
strcpy (Senetence2, LPCTSTR (myString));
return 1; }
调用完成后GlobalFree();
如果是前者,好象应该没什么问题吧,函数开头加上
AFX_MANAGE_STATE(AfxGetStaticModuleState()) ;
AFX_MANAGE_STATE(AfxGetStaticModuleState()) ;加和不加好像没有什么区别吧!我没有调用什么资源。
建议调用前初始化Sentence2先
刚才还是有问题、释放内存的时候。
是在调用的地方释放吧!这样写好像不行、该如何释放呢?int ReadFile(const TCHAR *filename )
{
.......
char*strMorph=NULL;
Trans( m_strGenbun, strMorph);
if (strMorph)
delete[] strMorph;
}
最好改成globalalloc, globalfree
Sentence2是EXE里的变量,在DLL里负值的时候,DLL会对Sentence2分配内存,这样,EXE中Sentence2 这个变量实效的时候CString释放内存实际释放的是DLL的内存,会出现访问越界,简单的方法是把CString Sentence2改成一个buffer
*Sentence2 = new char [myString.GetLength() + 1];
而且CString::GetLength返回值不考虑最后的'\0'结束位,长度需要+1才能保证不溢出。呵呵~~手误啊 ~~不好意思。
{
CString myString="";
.....
*Sentence2 = new char [myString.GetLength()];
strcpy (*Senetence2, myString);
return 1; }
我是说在这里如果申请了空间、肯定要在这里释放。因为EXE和DLL是两个空间。
但是释放的话返回值又没有了、矛盾啊!
我现在用了个办法是在Exe中调用两次这个函数。第一次 获得字符串大小
第二次申请空间返回值。就是这样做效率变低了。
{
CString myString="";
.....
Sentence2 = (char*)GlobalAlloc(GHND,myString.GetLength()+1); //^ ^
strcpy (Senetence2, LPCTSTR (myString));
return 1; }int ReadFile(const TCHAR *filename )
{
.......
char*strMorph=NULL;
Trans( m_strGenbun, strMorph);
if (strMorph)
GlobalFree(strMorph);
}
改成char*就可以了