托管c++访问普通c++的问题

jsjwql 2008-01-05 12:01:31
两个dll,一个是纯c++的A.dll,一个事CLI的B.dll.

A.dll中定义一个类

class Node;
Typedef vector<Node *> NodeContainer;

class Node
{
public:

int getNum()
{
return m_nodeContainer->size();
}

NodeContainer* getNodeContainer()
{
return m_nodeContainer;
}


NodeContainer *m_nodeContainer;

}



B.dll中
include A.dll里面的头文件和lib库

public ref class NodeWrapper
{
public:
void test()
{
//有一个Node的对象指针pNodeObj;它成员变量m_nodeContainer还有2个Node对象

int count = pNodeObj->getNum();// 成功 count = 2

NodeContainer *pContainer1 = pNodeObj->getNOdeContainer();
int sum = pContainer1->size(); // sum = 0, 也就是上面得到的指针失败, getNOdeContainer
//这个函数应该没问题,我在A.dll里面写了测试程序,没问题.
NodeContainer *pContainer2 = pNodeObj->m_nodeContainer;
sum = pContainer2->size(); //尝试直接访问成员变量指针,这个变量在A.dll里面测试也没问题,但这里sum还是0

}

}

这个问题在托管代码访问纯c++时出现的, 不知道这是什么问题,如何解决?
...全文
273 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
LostKingGK 2008-01-14
  • 打赏
  • 举报
回复
LZ,STL的数据结构是没有二进制标准的,因为它只是编译期的技术,不同的编译器处理STL的数据结构都有不同的二进制标准,所以你用DLL引出NodeContainer的指针,根本就没有用,你这里的pContainer1指针和pContainer2指针根本就无法访问到正确的数据;而int count = pNodeObj->getNum();之所以成功可能是因为Node类在同一个编译器下有相同的二进制标准,所以碰巧可以正常工作
jsjwql 2008-01-07
  • 打赏
  • 举报
回复
有道理,如果不行的话,只能这样。 谢谢
taodm 2008-01-07
  • 打赏
  • 举报
回复
to 楼主,你应该暴露的是对数据的操作方法而不是数据本身。
“封装”!!!
a0002 2008-01-07
  • 打赏
  • 举报
回复
如果用STL/CLI的话,就容易得多,可以直接把STL/CLI的容器通过CLR generic容器接口暴露给所有CLR语言。

可惜的是,VS 2008才有STL/CLI可用。

jsjwql 2008-01-06
  • 打赏
  • 举报
回复
通过a0002 提供的线索仔细阅读了下"How to export an instantiation of a Standard Template Library (STL) class and a class that contains a data member that is an STL object"

突然发现STL有这么多的局限性! 难道我想把c++里面的树形(tree)结构暴露出来,就这么难吗?
如果不用标准库的容器的话, 操作并暴露一个树形结构确实比较麻烦

不知道各位有何高见,谢谢
真相重于对错 2008-01-06
  • 打赏
  • 举报
回复
#include <iostream>

using namespace System;
using namespace System::Runtime::InteropServices;

// unmanaged struct
struct ListStruct {
int count;
double* item;
};

#pragma unmanaged

void UnmanagedTakesListStruct(ListStruct list) {
printf_s("[unmanaged] count = %d\n", list.count);
for (int i=0; i<list.count; i++)
printf_s("array[%d] = %f\n", i, list.item[i]);
}

#pragma managed

int main() {
ListStruct list;
list.count = 10;
list.item = new double[list.count];

Console::WriteLine("[managed] count = {0}", list.count);
Random^ r = gcnew Random(0);
for (int i=0; i<list.count; i++) {
list.item[i] = r->NextDouble() * 100.0;
Console::WriteLine("array[{0}] = {1}", i, list.item[i]);
}

UnmanagedTakesListStruct( list );
delete list.item;
}

托管代码访问非托管代码
jsjwql 2008-01-05
  • 打赏
  • 举报
回复
不太理解你指的封装成标准DLL, 我是把它封装在一个dll里面的,把这个类export出来了.
jsjwql 2008-01-05
  • 打赏
  • 举报
回复
换一个方式问这个问题

怎么从托管c++中直接访问纯c++里面的容器? 当然是在两个模块间.谢谢
  • 打赏
  • 举报
回复
一般是不导出类,封装成标准DLL
jsjwql 2008-01-05
  • 打赏
  • 举报
回复
不知道有没有什么好的建议让我跟踪这个问题
  • 打赏
  • 举报
回复
导出类的问题很难解决
awpatp 2008-01-05
  • 打赏
  • 举报
回复
帮你顶一下
a0002 2008-01-05
  • 打赏
  • 举报
回复
给你一篇文章,自己参考吧。实在不行,帖出完整一点的代码,才能更好的定位错误。

http://blog.csdn.net/su317/archive/2007/12/17/1944021.aspx#
  • 打赏
  • 举报
回复
那就不清楚了,从来没有写过非标准DLL
jsjwql 2008-01-05
  • 打赏
  • 举报
回复
其实这些都是我一个人写的,都是在VS2005下写的,都是在debug下 :)
a0002 2008-01-05
  • 打赏
  • 举报
回复
就是实现vector的DLL或者lib的版本不同,比如一个debug版另一个release版,一个vc7一个vc8等等。
jsjwql 2008-01-05
  • 打赏
  • 举报
回复
使用com稍微复杂了点

两个DLL联接的不同的crt dll?
a0002 2008-01-05
  • 打赏
  • 举报
回复
我估计问题可能出在两个DLL联接的不同的crt dll,导致两个DLL中相同的vector指向不同的class地址。
  • 打赏
  • 举报
回复
将C++的class封装成COM再使用.

使用导出类会给自己添加很多解决不了的问题.没有二进制兼容,甚至同一个编译器都无法正常使用dll中的class
a0002 2008-01-05
  • 打赏
  • 举报
回复
DLL中导出STL类和使用了STL类的自定义类会有很多限制!

建议楼主直接用数组或者CLR generic容器在C++/CLI和C#之间交换数据。


加载更多回复(2)

64,643

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧