我要在接口函数里返回一个容器,网上说会有问题,最好是把容器封装到结构体里面,所以我写了一个类,里面含有两个容器,一个vector一个map。
但是当我返回这个类的对象时,并在APP里定义了相同的类,来接收这个对象,可是打印出来之后的东西很乱,是指针指错了内存的症状(我在dll定义的其他毫无相关的变量都打印了出来)。
我想问的是,我这样做是不是可行的。如果可行哪里出错了呢(内存分配?)
如果不行有什么办法传递这个容器呢?(用数组?)
谢谢
15 个解决方案
#1
dll最初是用c标准的,因此对容器,TForm等这些最好用activex来做更通用。
#2
因为我要写TCP通信程序,而我用了VCL里的TSocketClient这个组件,只能创建一个窗体并且做成dll才能被比如VC调用
#3
好吧,因为没人回答,所以我尝试用别的方法。
现在我不在接口传递容器了,改用所有对容器的操作都在dll里实现
但又有新的问题,我在dll里定义了一个vector并push_back了一些数据,这个循环结束之后我立即打印出这些数据,但是。。。。。
还是打印乱码?这个貌似是内存管理出了问题,可是。。。我不知道怎么解决????
现在我不在接口传递容器了,改用所有对容器的操作都在dll里实现
但又有新的问题,我在dll里定义了一个vector并push_back了一些数据,这个循环结束之后我立即打印出这些数据,但是。。。。。
还是打印乱码?这个貌似是内存管理出了问题,可是。。。我不知道怎么解决????
#4
没人啊。。。。
#5
如果在接口里直接传递STL容器,会发生问题,因为很多STL容器含有静态成员,APP和DLL的内存空间又不一样
在dll里定义了一个vector并push_back了一些数据,这个循环结束之后我立即打印出这些数据
请贴代码
在dll里定义了一个vector并push_back了一些数据,这个循环结束之后我立即打印出这些数据
请贴代码
#6
我找到了,我用map容器insert了指针,但是之后立刻删除了,所以会出错。但是现在还有点问题。我大概写下代码
whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}
现在的问题是当str = NULL时,会出现异常,如果不为空则可以;这是为什么呢?
whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}
现在的问题是当str = NULL时,会出现异常,如果不为空则可以;这是为什么呢?
#7
whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}
#8
[code=C/C++][whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}]
抱歉,竟然不会插入代码。。。。
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}]
抱歉,竟然不会插入代码。。。。
#9
BCB6的 std::map 與 VC的std::map , 不同編譯器其STL類的內存布局可能不一樣,這就是DLL中不傳遞STL實例的一個內在原因。
另外,DLL與調用程序使用不同的內存空間,也使得STL類(map vector)的操作要十分小心,不小心就搞壞了內存。
一般不攷慮在DLL接口中傳遞STL類。除非用同一個編譯器。
另外,DLL與調用程序使用不同的內存空間,也使得STL類(map vector)的操作要十分小心,不小心就搞壞了內存。
一般不攷慮在DLL接口中傳遞STL類。除非用同一個編譯器。
#10
#11
但都是设计到字符串,而且还有一一对应的关系,如果不用STL用什么啊 char**?
#12
whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str = NULL;
map<string, string>::iterator iter = map1.find(str);//有人说str不能为NULL,为什么啊
if(iter != map1.end())
{
...
}
#13
1、有人说str不能为NULL,为什么啊
std::string 構造或賦值,不接受 NULL 指針 可以使用 "" ,但不能用 NULL ;
2、但都是设计到字符串,而且还有一一对应的关系,如果不用STL用什么啊 char**?
如果內部要使用 std::map , 建議DLL寫接口將 std::map 封裝起來,不曝露std::map給外部調用。DLL內使用STL類,需要做黑盒處理,也就是DLL接口中看不見STL模板類。
如果非得將 std::map 曝露出來,那麼你得將 std::map 的頭文件同樣發佈,這就相當於要求別人與你用同樣的 STL 庫版本,而且還得檢查編譯選項,以保障內存佈局一致,函數調用方式一樣。或者你重寫一個可供共用的 std::map 類。
std::string 構造或賦值,不接受 NULL 指針 可以使用 "" ,但不能用 NULL ;
2、但都是设计到字符串,而且还有一一对应的关系,如果不用STL用什么啊 char**?
如果內部要使用 std::map , 建議DLL寫接口將 std::map 封裝起來,不曝露std::map給外部調用。DLL內使用STL類,需要做黑盒處理,也就是DLL接口中看不見STL模板類。
如果非得將 std::map 曝露出來,那麼你得將 std::map 的頭文件同樣發佈,這就相當於要求別人與你用同樣的 STL 庫版本,而且還得檢查編譯選項,以保障內存佈局一致,函數調用方式一樣。或者你重寫一個可供共用的 std::map 類。
#14
哦,谢谢了。我按照你说的做了,现在可以运行。内部使用STL还是可以的。。
先结贴了。
不过还有另外一个思考,希望还能回答一下哈。
既然内部使用STL可以,那内部使用C++Builder的AnsiString类型行不行呢,而且dll要被VC调用,而且VC那边没有装BCB
谢谢
先结贴了。
不过还有另外一个思考,希望还能回答一下哈。
既然内部使用STL可以,那内部使用C++Builder的AnsiString类型行不行呢,而且dll要被VC调用,而且VC那边没有装BCB
谢谢
#15
可以啊,用啥都可以,但是要保证DLL调用的库(比如CB的库)被编译进DLL或随DLL发布
#1
dll最初是用c标准的,因此对容器,TForm等这些最好用activex来做更通用。
#2
因为我要写TCP通信程序,而我用了VCL里的TSocketClient这个组件,只能创建一个窗体并且做成dll才能被比如VC调用
#3
好吧,因为没人回答,所以我尝试用别的方法。
现在我不在接口传递容器了,改用所有对容器的操作都在dll里实现
但又有新的问题,我在dll里定义了一个vector并push_back了一些数据,这个循环结束之后我立即打印出这些数据,但是。。。。。
还是打印乱码?这个貌似是内存管理出了问题,可是。。。我不知道怎么解决????
现在我不在接口传递容器了,改用所有对容器的操作都在dll里实现
但又有新的问题,我在dll里定义了一个vector并push_back了一些数据,这个循环结束之后我立即打印出这些数据,但是。。。。。
还是打印乱码?这个貌似是内存管理出了问题,可是。。。我不知道怎么解决????
#4
没人啊。。。。
#5
如果在接口里直接传递STL容器,会发生问题,因为很多STL容器含有静态成员,APP和DLL的内存空间又不一样
在dll里定义了一个vector并push_back了一些数据,这个循环结束之后我立即打印出这些数据
请贴代码
在dll里定义了一个vector并push_back了一些数据,这个循环结束之后我立即打印出这些数据
请贴代码
#6
我找到了,我用map容器insert了指针,但是之后立刻删除了,所以会出错。但是现在还有点问题。我大概写下代码
whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}
现在的问题是当str = NULL时,会出现异常,如果不为空则可以;这是为什么呢?
whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}
现在的问题是当str = NULL时,会出现异常,如果不为空则可以;这是为什么呢?
#7
whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}
#8
[code=C/C++][whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}]
抱歉,竟然不会插入代码。。。。
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str;
map<string, string>::iterator iter = map1.find(str);
if(iter != map1.end())
{
...
}]
抱歉,竟然不会插入代码。。。。
#9
BCB6的 std::map 與 VC的std::map , 不同編譯器其STL類的內存布局可能不一樣,這就是DLL中不傳遞STL實例的一個內在原因。
另外,DLL與調用程序使用不同的內存空間,也使得STL類(map vector)的操作要十分小心,不小心就搞壞了內存。
一般不攷慮在DLL接口中傳遞STL類。除非用同一個編譯器。
另外,DLL與調用程序使用不同的內存空間,也使得STL類(map vector)的操作要十分小心,不小心就搞壞了內存。
一般不攷慮在DLL接口中傳遞STL類。除非用同一個編譯器。
#10
#11
但都是设计到字符串,而且还有一一对应的关系,如果不用STL用什么啊 char**?
#12
whie(getline(infile, ss))
{
string s1 = ss.substr(...);//...省略了
string s2 = ss.substr(...);
map<string, string> map1;
map1.insert(make_pair(s1, s2));
}
char* str = NULL;
map<string, string>::iterator iter = map1.find(str);//有人说str不能为NULL,为什么啊
if(iter != map1.end())
{
...
}
#13
1、有人说str不能为NULL,为什么啊
std::string 構造或賦值,不接受 NULL 指針 可以使用 "" ,但不能用 NULL ;
2、但都是设计到字符串,而且还有一一对应的关系,如果不用STL用什么啊 char**?
如果內部要使用 std::map , 建議DLL寫接口將 std::map 封裝起來,不曝露std::map給外部調用。DLL內使用STL類,需要做黑盒處理,也就是DLL接口中看不見STL模板類。
如果非得將 std::map 曝露出來,那麼你得將 std::map 的頭文件同樣發佈,這就相當於要求別人與你用同樣的 STL 庫版本,而且還得檢查編譯選項,以保障內存佈局一致,函數調用方式一樣。或者你重寫一個可供共用的 std::map 類。
std::string 構造或賦值,不接受 NULL 指針 可以使用 "" ,但不能用 NULL ;
2、但都是设计到字符串,而且还有一一对应的关系,如果不用STL用什么啊 char**?
如果內部要使用 std::map , 建議DLL寫接口將 std::map 封裝起來,不曝露std::map給外部調用。DLL內使用STL類,需要做黑盒處理,也就是DLL接口中看不見STL模板類。
如果非得將 std::map 曝露出來,那麼你得將 std::map 的頭文件同樣發佈,這就相當於要求別人與你用同樣的 STL 庫版本,而且還得檢查編譯選項,以保障內存佈局一致,函數調用方式一樣。或者你重寫一個可供共用的 std::map 類。
#14
哦,谢谢了。我按照你说的做了,现在可以运行。内部使用STL还是可以的。。
先结贴了。
不过还有另外一个思考,希望还能回答一下哈。
既然内部使用STL可以,那内部使用C++Builder的AnsiString类型行不行呢,而且dll要被VC调用,而且VC那边没有装BCB
谢谢
先结贴了。
不过还有另外一个思考,希望还能回答一下哈。
既然内部使用STL可以,那内部使用C++Builder的AnsiString类型行不行呢,而且dll要被VC调用,而且VC那边没有装BCB
谢谢
#15
可以啊,用啥都可以,但是要保证DLL调用的库(比如CB的库)被编译进DLL或随DLL发布