C++动态连接库怎么使用System::String?

不假思索 2014-12-20 04:06:00
准备用VS2010 C++开发一个动态连接库:打开登录窗口,返回用户名和密码。
但是在定义String类型成员变量时出了问题,头文件中定义登录信息结构如下:



using namespace System;

struct __declspec(dllexport) LoginInfo{
String sUser;
String sPassword;
}



编译时提示两个错误:
1、error C3149: “System::String”: 此处没有顶级“^”,不能使用此类型
2、error C3265: 无法声明托管“sUser”(在非托管“LoginInfo”中) 不能声明全局或静态变量,也不能声明引用 gc 堆中对象的本机类型成员

这是怎么回事?多谢指教!
...全文
558 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
不假思索 2014-12-22
  • 打赏
  • 举报
回复
这个有用!行得通。 我下一步工作应该要用上命名空间和托管类了,等我慢慢再研究一下。先结贴吧。 谢谢了,各位!
引用 10 楼 Saleayas 的回复:
使用 gcroot< String >. 托管的类型不能直接内置到本地类型中。
Saleayas 2014-12-22
  • 打赏
  • 举报
回复
使用 gcroot< String >. 托管的类型不能直接内置到本地类型中。
不假思索 2014-12-21
  • 打赏
  • 举报
回复
1.一个命名空间 = namespace DLL ? 2.一个托管类 = public ref class Logger? 这是命名空间和托管类的定义吗? 4.不需要 __declspec(dllexport) ......... 意思是引用动态连接库的时候只要using namespace DLL就可以了,是这样吗?
引用 8 楼 iyomumx 的回复:
如果你打算写给C#/VB.net用的DLL,那么你需要: 1.一个命名空间,因为C#和VB均不能识别全局命名空间中的类 2.一个托管类,因为C#和VB均不能识别全局函数 3.在托管类中声明托管方法,可以是静态的 4.不需要 __declspec(dllexport) ,因为类成员信息已经内嵌于程序集中,不需要”导出“ 比如这样:
namespace DLL
{
    using namespace System;
    using System::Runtime::InteropServices::Marshal;

    public ref class Logger
    {
    private:
        IntPtr packageNameStr;
        PackageIDs packageID;
    public:
        Logger(PackageIDs id, String^ name)
            : packageID(id), packageNameStr(Marshal::StringToCoTaskMemAnsi(name))
        {
           
        }

        ~Logger()
        {
            Marshal::FreeCoTaskMem(packageNameStr);
        }

        void EnableLogging(String^ logFilePath, LogLevel filter, LogOption options, unsigned long maxSize, bool archive);

        void DisableLogging(String^ logFilePath);

    };
}
iyomumx 2014-12-21
  • 打赏
  • 举报
回复
如果你打算写给C#/VB.net用的DLL,那么你需要: 1.一个命名空间,因为C#和VB均不能识别全局命名空间中的类 2.一个托管类,因为C#和VB均不能识别全局函数 3.在托管类中声明托管方法,可以是静态的 4.不需要 __declspec(dllexport) ,因为类成员信息已经内嵌于程序集中,不需要”导出“ 比如这样:
namespace DLL
{
    using namespace System;
    using System::Runtime::InteropServices::Marshal;

    public ref class Logger
    {
    private:
        IntPtr packageNameStr;
        PackageIDs packageID;
    public:
        Logger(PackageIDs id, String^ name)
            : packageID(id), packageNameStr(Marshal::StringToCoTaskMemAnsi(name))
        {
           
        }

        ~Logger()
        {
            Marshal::FreeCoTaskMem(packageNameStr);
        }

        void EnableLogging(String^ logFilePath, LogLevel filter, LogOption options, unsigned long maxSize, bool archive);

        void DisableLogging(String^ logFilePath);

    };
}
不假思索 2014-12-21
  • 打赏
  • 举报
回复
能详细说说吗?
引用 6 楼 jiangsheng 的回复:
net的String也只有.Net语言可以用,而且接口就不能用导出函数的方式,需要写成托管的类。
蒋晟 2014-12-21
  • 打赏
  • 举报
回复
net的String也只有.Net语言可以用,而且接口就不能用导出函数的方式,需要写成托管的类。
不假思索 2014-12-20
  • 打赏
  • 举报
回复
是啊,我也试过加^了。 这个dll开发出来是给非C++调用的,所以我的调用思路是: 1、先调用一个函数,例如getLoginInfo(); 2、getLoginInfo()打开模式窗口,取得用户名和密码; 3、getLoginInfo()返回一个指向LoginInfo的指针。 所以LoginInfo要能被其它编程语言识别,但CString是C++的字符串,别的语言识别不了。所以就想把用户名和密码定义成.net的String。
微型蚂蚁 2014-12-20
  • 打赏
  • 举报
回复
试了一下应该不行, 因为String是托管类型,struct中不能直接使用托管成员 可以把struct用ref struct声明为托管类型, 但是用__declspec(dllexport)/__declspec(dllimport)又不导入导出托管类型
微型蚂蚁 2014-12-20
  • 打赏
  • 举报
回复
ref struct LoginInfo{ String^ sUser; String^ sPassword; };
微型蚂蚁 2014-12-20
  • 打赏
  • 举报
回复
struct __declspec(dllexport) LoginInfo{ String^ sUser; String^ sPassword; }
不假思索 2014-12-20
  • 打赏
  • 举报
回复
4、5行都是这两个错误。

65,187

社区成员

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

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