【问题标题】:Dll in C++ 2013 needst to return a string to VB.netC++ 2013 中的 Dll 需要向 VB.net 返回一个字符串
【发布时间】:2016-09-01 13:51:22
【问题描述】:

我很困惑...我是一名 VB.net 程序员,我需要创建一个带有接收器的接口。向接收器发送数据没问题,我可以对频率、带宽和类似的东西进行编程……我不得不使用 C++ 与接收器通信。所以我决定试一试,用 C++ 创建一个 dll 并在 VB.net 中制作 GUI。但是,当我想向接收者询问信息时,我被卡住了......

我的 C++ 代码如下所示

char __stdcall Q_BW(){
    MyPR100::sendSCPI(TCPsock, "SENS:BAND?\n");
    char pRxBuf[256];
    int len = recv(TCPsock, pRxBuf, sizeof(pRxBuf), 0);
    if (len < 0) len = 0; pRxBuf[len] = '\0';
    puts(pRxBuf);
    return  pRxBuf;
}

所以基本上,向接收器发送命令,并将结果放入缓冲区......现在这个缓冲区需要返回到 VB.net,这就是我失败的地方...... 编译的时候报错

无法从 'char[256]' 转换为 'char'

我可以看到我做错了什么,但显然我无法找到解决方案... dll 可以正常工作以将数据发送到接收器,因此该部分正在工作... 完整地说,这是VB.net的代码……

 Private Declare Function Q_BW Lib "PR100Dll.dll" () As String

Dim Res As String = ""
Res = Q_BW()
MsgBox(Res, MsgBoxStyle.Information)

我知道这可能是一个菜鸟问题,但我真的被困在这里......因为我的 C++ 不是那么好(这是一个 uderstatement),而且英语不是我的母语,如果我我会很高兴得到了一个不那么难的答案,我可以从中学习...哦,请注意,我已经在谷歌上搜索了 2 周,而且我真的到了最后...

提前谢谢...

【问题讨论】:

  • VB.NET 中的 String 映射到非托管代码中的 BSTR。除非您在 recv 调用中读取 UTF-16 编码字符,否则您需要将数据转换为 UTF-16。
  • char __stdcall Q_BW() 返回单个字符,而不是字符串。此外,为了与 VB 交互,您需要一个与 char*std::string 完全不同的 bstr_t
  • 我可以举一些例子吗?那将是非常棒的......
  • 我添加示例太晚了...如果我将其更改为 BSTR __stdcall Q_BW() 那么我会收到错误,它需要在 stdcall 之前使用分号...。我是这里真的很困惑.....
  • 这是您遇到的一个错误。另一个是 BSTR 类型是未知的(这就是它的原因)。此外,简单地更改返回类型不会解决您的问题。 BSTRs 也有不同的语义。我在第一条评论中提供了一个链接。您似乎没有为问题(和解决方案)的复杂性做好准备。还有很多需要考虑(例如字符编码、可能的转换,或者可能完全使用另一种容器类型,以防无法转换)。

标签: c++ arrays vb.net string dll


【解决方案1】:

我为你写了一个例子:

1.TestDll.cpp(dll中的函数)

#include "stdafx.h"

char* __stdcall ReadString()
{
    return "ABCDEFG";
}

2.TestDll.def(导出ReadString函数)

LIBRARY     TestDll
EXPORTS
    ReadString

3.TestCS(CSharp 演示)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace TestCS
{
    class Program
    {
        [DllImport("TestDll.dll", CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr ReadString();

        static void Main(string[] args)
        {
            IntPtr t = ReadString();
            String result = Marshal.PtrToStringAnsi(t);
        }
    }
}

4.TestVB(VB演示)

Imports System.Runtime.InteropServices

Module Module1
    Private Declare Function ReadString Lib "TestDll.dll" () As IntPtr

    Sub Main()
        Dim t As IntPtr
        Dim result As String

        t = ReadString
        result = Marshal.PtrToStringAnsi(t)
    End Sub

End Module

dll项目、CS项目、VB项目应设置相同的字符集。

【讨论】:

  • 你太棒了......今天我生病了,下班回家了,但我一定会在星期一试试这个!感谢您提供清晰的示例。现在我可以再深入一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 2021-12-01
  • 1970-01-01
相关资源
最近更新 更多