Tag: c ++ cli

从const char *复制到字节数组C ++ / c #interop Marshal :: Copy

我正在尝试将C ++中的图像发送到C#,并使用C ++管理的interop(marshaling)。 image->getStream()从字符串返回一个const char* 。 我的Marshal::Copyfunction有exception。 mscorlib.dll中发生了未处理的’System.AccessViolationException’类型exception 附加信息:尝试读取或写入受保护的内存。 这通常表明其他内存已损坏。 我是否正在为从const char*到字节数组的副本做正确的事情? 我的dll是在VS2010中使用ASCII字符集编译的。 array^ OsgViewer::getLastImage() { array^ byteArray; m_ImageQueue->lock(); int index = m_ImageQueue->getCurrentImageIndex(); std::shared_ptr image = m_ImageQueue->getImage(static_cast(index)); if( image && image->isValid() == true) { int wLen = image->getStreamSize(); char* wStream = const_cast(image->getStream()); byteArray = gcnew array(wLen); // convert native pointer to System::IntPtr with C-Style cast […]

Base64String和hex之间的转换

我在我的C ++ / CLI项目ToBase64String了一个字符串,如/MnwRx7kRZEQBxLZEkXndA==我想将此字符串转换为hex表示,如何在C ++ / CLI或C#中执行此操作?

无法通过AppDomains传递GCHandle:没有代表的解决方案?

我在c ++中有基础库,客户端应用程序在C#中。 有c ++ / cli接口可以从C#访问c ++ api。 一切都运行良好,直到多个应用程序域没有像NUnit或WCF托管一样发挥,即有一个应用程序域。 我已经在cli中的gcroot中存储了托管对象以进行回调。 我已经读过这是应用程序域问题的根本原因(“无法通过AppDomains传递GCHandle”),因为它们没有应用程序域信息( http://lambert.geek.nz/2007/05/29/unmanaged -appdomain-callback / )。 有人建议使用委托,但我的底层c ++层期望对象不是函数指针( http://www.lenholgate.com/blog/2009/07/error-cannot-pass-a-gchandle-across-appdomains.html )。 我也尝试过IntPtr,但在这种情况下,我无法在回调期间将其强制转换为我的托管对象。 UPDATE 让我再详细说明一下我的问题。 我在C#中有“Receiver”类 ,它作为输入参数传递给api之一。 此接收器对象用于回调。 在C ++ / CLI中,我创建了一个Native / unmanaged类“ObjectBinder” ,它与托管的Receiver类具有相同的副本(具有相同的方法)。 它保存了gcroot中托管接收者对象的引用 。 当我们从C#调用api时,它来到CLI层, app域是“client exe” 。 我们在gcroot的ObjectBinder中存储参数“managed receiver object”,并将本机ObjectBinder对象的引用传递给C ++。 现在后端代码(c ++和c)向c ++层发送一个asyn回调 ( 新线程 ),该层使用ObjectBinder对象向CLI发送回调用。 现在我们在ObjectBinder对象的CLI层中。 但是App域已被更改(在WCF或NUNIT或任何其他创建它自己的App域的服务的情况下,在编译时不知道) 。 现在我想访问存储在gcroot中的托管Receiver对象,以便将回调发送回C#,但它给出了APP DOMAIN错误。 我也试过IntPtr和IUnknown *而不是gcroot与Marshal […]

包装C ++以在C#中使用

好吧,基本上我要包装一个大的C ++项目(Recast) ,以便我可以在我的C#项目中使用它。 我一直试图这样做一段时间,这就是我到目前为止所做的。 我正在使用C ++ / CLI来包装我需要的类,以便我可以在C#中使用它们。 但是,我的C#项目中还需要大量的结构和枚举。 那么如何包装这些呢? 我现在使用的基本方法是将dllexport调用添加到本机c ++代码,编译为dll / lib,将此lib添加到我的C ++ / CLI项目并导入c ++头文件,然后将CLI项目编译为dll,最后添加此dll作为我的C#项目的参考。 我感谢任何帮助。 这里有一些代码。我需要可管理的方法,因为C ++项目非常庞大。 //**Native unmanaged C++ code //**Recast.h enum rcTimerLabel { A, B, C }; extern “C” { class __declspec(dllexport) rcContext { public: inline rcContect(bool state); virtual ~rcContect() {} inline void resetLog() { if(m_logEnabled) doResetLog(); } protected: […]

在使用C ++ / CLI代码传递的参数中,^符号是否替换了C#的“ref”?

在C#中,通过引用传递: void MyFunction(ref Dog dog) 但是到目前为止我看到的C ++ / CLI代码示例中没有使用ref ,而是使用了^符号: void MyFunction(Dog ^ dog) 当参数传递时,是否使用^符号直接替换ref ? 还是有其他一些我不知道的含义? 附加问题:我也看到了很多: Dog ^ myDog = gcnew Dog(); 看起来它像C ++中的* (指针)一样使用。它的工作原理是否类似? 谢谢!

使用std :: string为PInvoke定制Marshaler

免责声明:C ++ / CLI Noob问题 我正在尝试在签名中具有std :: string的C ++ DLL上使用PInvoke。 目前我只是测试:我的目标是将字符串传递给本机DLL,然后返回它。 本机导出如下所示: #define NATIVE_CPP_API __declspec(dllexport) NATIVE_CPP_API void hello_std(std::string inp, char* buffer) { const char* data = inp.data(); strcpy(buffer, data); } 我正在尝试使用自定义封送器以正常方式对其进行PInvoke: [DllImport(“native_cpp.dll”, EntryPoint = “?hello_std@@YAPADV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z”, CallingConvention = CallingConvention.Cdecl)] private static extern void hello_std( [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(clr_wrapper.string_marshaler))] String inp, StringBuilder buffer); static void Main(string[] args) […]

使用托管C ++ / CLI中的C#扩展方法

如果我的术语有点偏离,请原谅我。 我对托管C ++ / CLI的了解非常有限。 我有一个MFC应用程序,使用启用了/ clr选项的DLL。 这个dll使用几个C#dll与使用WCF的服务器通信。 在大多数情况下,这工作正常。 在其中一个C#dll中,我向System.Net.IPAddress类添加了一个扩展方法,该类将检索IPAddress对象的子网掩码(使用UnicastIPAddressInformation类及其IPv4Mask)。 扩展方法在C#方面运行良好,但我无法弄清楚如何在托管C ++ / CLI代码中使用它。 首先,这甚至可能吗? 如果是这样,托管C ++ / CLI端的语法是什么样的? 我必须使用/ clr:pure选项才能使用吗? 以下是扩展方法的示例: using System.Net; using System.Net.NetworkInformation; public static class IPAddressExtensions { public static IPAddress GetSubnetMask(this IPAddress address) { UnicastIPAddressInformation addressInfo = address.GetAddressInformation(); // elided return ((addressInfo != null) ? addressInfo.IPv4Mask : null); } } 在我的托管C […]

托管C ++ / CLI方法中的可选参数

当在C#中使用时,如何在C ++ / CLI中声明具有可选参数的托管方法? 我使用Optional和DefaultParameterValue属性修饰了参数(请参阅: 如何编码默认参数值 ),但只有Optional属性才被尊重。 C ++ / CLI: public ref class MyClass1 { public: MyClass1([System::Runtime::InteropServices::Optional] [System::Runtime::InteropServices::DefaultParameterValue(2)] int myParam1) ↑ { System::Console::WriteLine(myParam1); } }; C#: var myInstance1 = new MyClass1(); // compiles and runs 输出 : 0 预期产出: 2 Visual C#IntelliSense: MyClass1.MyClass1([int myParam1 = 0]); // wrong default value ↑ 编辑:仔细观察反汇编程序会发现C ++ / […]

Windows Azure未找到C ++ / CLI项目的DLL

我有一个包含非托管C压缩库的C ++ / CLI项目,该项目由调用C ++ Compress函数的MVC3项目引用。 一切都在本地工作正常,但当我将解决方案发布到Azure云时,我得到一个错误,说它无法找到模块/ dll: 无法加载文件或程序集“LZGEncoder.DLL”或其依赖项之一。 指定的模块无法找到。 为什么找不到DLL文件? 它是错误的地方还是正在编译? 有什么方法可以检查吗? 谢谢!

从C ++ / CLI调用C#dll函数

我有一个C# dll。 代码如下: public class Calculate { public static int GetResult(int arg1, int arg2) { return arg1 + arg2; } public static string GetResult(string arg1, string arg2) { return arg1 + ” ” + arg2; } public static float GetResult(float arg1, float arg2) { return arg1 + arg2; } public Calculate() { } } 现在,我打算用这种方式从C++调用这个dll。 […]