簡體   English   中英

將C#字符串傳遞給C ++ / CLI不會在CPP程序中顯示字符串值

[英]Passing a C# string to C++/CLI does not show the string value in the CPP program

我想通過CLI / C ++從C ++調用C#函數。

C#代碼

private string _text = " ";

public void setText(string text)
{
    // _text = text;
    _text = "HI World";
}

理想情況下,setText應該僅包含注釋行。 _text =“ HI World”是一個示例。

public string getText()
{
    return _text;
}

C ++ / CLI代碼

標頭:

gcroot<Bridge> _managedObject;

virtual void setText(std::string text);
virtual std::string getText();

CPP文件

std::string CStringBridge::getText()
{

// _managedObject = gcnew Bridge(); 返回(marshal_as(_managedObject-> getText())); }

void CStringBridge::setText(std::string text)
{

// _managedObject = gcnew Bridge(); _managedObject-> setText(gcnew System :: String(text.c_str())); }

IStringBridgeWrapper* IStringBridgeWrapper::CreateInstance(void)
{
return ((IStringBridgeWrapper *)new CStringBridge());
}

注意:當我使用以下代碼時

virtual void setText(System::String^ text);
virtual System::String^ getText();

我收到以下錯誤3395

* __ declspec(dllexport)不能應用於具有__clrcall調用約定的函數*

,所以我堅持使用std :: string

當我使用C ++ / CLI代碼中的庫並從我的C ++程序中調用時,應打印“ Hi World”; 相反,什么都沒有打印

C ++控制台應用程序

IStringBridgeWrapper *pBridge = IStringBridgeWrapper::CreateInstance();

pBridge->setText(std::string("I am here"));
pBridge->getText();

我認為該字符串未正確傳遞。

任何解決它的想法將不勝感激。

編輯

我已經在注釋后更新了代碼,但是什么也沒有顯示。

gcroot創建一個句柄,但不為其分配內存。 但是由於Bridge沒有分配內存,因此該應用程序無法正常工作。我的代碼在本文的同一行中-http: //www.codeproject.com/Articles/10020/Using-managed-code-in-an-非托管應用程序

我想通過CLI / C ++從C ++調用C#函數。

等待...您想從C#調用C ++函數,對吧? 這就是C ++ / CLI的優點。 包裝C ++代碼以在托管環境中訪問。 如果您真的想從C ++調用C#代碼,則應考慮使用COM注冊您的C#代碼。 如果為此使用C ++ / CLI,則整個C ++程序將被拖入.NET世界,並且您可能從一開始就使用C#。

在C ++ / CLI中,您的ref(.NET)類的整個公共類接口應僅由托管類型組成。 那應該是System::String^而不是std::string

COM是您的朋友:

在C#中創建接口

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


namespace CsharpLibrary
{
   // Since the .NET Framework interface and coclass have to behave as 
   // COM objects, we have to give them guids.
   [Guid("56A868B1-0AD4-11CE-B03A-0020AF0BA770"),
    InterfaceType(ComInterfaceType.InterfaceIsDual)]
   public interface IStringHolder
   {
      String GetText();
      void SetText(String s);
   }
}

實現C#接口:

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

namespace CsharpLibrary
{
   [Guid("C6659361-1625-4746-931C-36014B146679")]
   public class MyStringHolder : IStringHolder
   {
      String _text;

      public String GetText()
      {
         return this._text;
      }

      public void SetText(String value)
      {
         _text = value;
      }

   }
}

從C ++創建並調用C#對象

#include <windows.h>
#include <stdio.h>

#pragma warning (disable: 4278)

// To use managed-code servers like the C# server, 
// we have to import the common language runtime:
#import <mscorlib.tlb> raw_interfaces_only


#pragma warning (disable: 4278)

// To use managed-code servers like the C# server, 
// we have to import the common language runtime:
#import <mscorlib.tlb> raw_interfaces_only

#import "..\CsharpLibrary\bin\Debug\CsharpLibrary.tlb" no_namespace named_guids





int main(int argc, char* argv[])
{
   HRESULT hr = S_OK;

   IStringHolder *pStringHolder = NULL;

   //
   // Initialize COM and create an instance of the InterfaceImplementation class:
   //
   CoInitialize(NULL);

   hr = CoCreateInstance(   __uuidof(MyStringHolder),
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           __uuidof(IStringHolder),
                           reinterpret_cast<void**>(&pStringHolder));

   if(SUCCEEDED(hr))
   {
      _bstr_t sHelloWorld = SysAllocString( L"Hello, World" );

      hr = pStringHolder->SetText(sHelloWorld);

      SysFreeString(sHelloWorld);
   }


   //
   // Be a good citizen and clean up COM
   //
   CoUninitialize();

   return hr;
}

在C#端,您必須生成類型庫並通過構建后事件注冊類:

生成類型庫:“ $(FrameworkSDKDir)bin \\ NETFX 4.0 Tools \\ tlbexp.exe”“ $(TargetPath)” /out:"$(TargetDir)$(TargetName).tlb“

注冊該類:C:\\ Windows \\ Microsoft.NET \\ Framework \\ v4.0.30319 \\ RegAsm.exe“ $(TargetPath)”

請享用!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM