在过去的几年里,我一直是一名本地C++程序员.现在我们从头开始一个新项目.那么您对以C++\CLI转移而牺牲平台无关代码的想法是什么?转换到C++\CLI可以获得任何特殊优势吗?
InternalsVisibleTo不适用于我的托管C++项目,但它适用于我的C#项目.任何帮助,将不胜感激.这是一个简化的布局.
项目A - C#,具有我想从B/C访问的内部属性.
项目B - 托管C++.引用一个.
项目Ç - C#,引用一个.
所有项目都使用相同的密钥签名.使用ILDASM或Reflector查看已编译的程序集,表明它们都已正确签名(当我注释掉内部属性用法时).
在Project A的 AssemblyInfo.cs中,我有以下InternalsVisibleTo;
[assembly: InternalsVisibleTo( "B, " +
"PublicKey=00240000048000009400000006020000002400005253413100040000010001007" +
"50098646D1C04C2A041FAAF801521A769535DE9A04CD3B4DEDCCBF73D1A6456BF4FE5881451" +
"0E84983C72D0460B8BA85C52A9CACDC4A0785A08E247C335884C2049ECFE6B2C5E20A18FE4B" +
"9BFF009ADA232E980D220B3C9586C9C5EE29C29AEE8853DB7BB90CF5A4C704F5244E1A1085C" +
"4306008535049A0EBB00FE47E78DCB" )]
[assembly: InternalsVisibleTo( "C, " +
"PublicKey=00240000048000009400000006020000002400005253413100040000010001007" +
"50098646D1C04C2A041FAAF801521A769535DE9A04CD3B4DEDCCBF73D1A6456BF4FE5881451" +
"0E84983C72D0460B8BA85C52A9CACDC4A0785A08E247C335884C2049ECFE6B2C5E20A18FE4B" +
"9BFF009ADA232E980D220B3C9586C9C5EE29C29AEE8853DB7BB90CF5A4C704F5244E1A1085C" +
"4306008535049A0EBB00FE47E78DCB" )]
Run Code Online (Sandbox Code Playgroud)
钥匙被'切',所以我知道它们是正确的.
当我尝试编译时,A&C编译正常,但项目B失败了
Error 1 error C3767: 'A::MyClass::MyProperty::get': candidate function(s) not accessible c:\Users\<snip>\CppClass.cpp 201 B
Run Code Online (Sandbox Code Playgroud)
MSDN文档说这适用于C++.我需要做一个bug还是别的什么?
是否有另一种方法可以保护财产,使其只能由我签署的集合使用?我知道我可以保护我的所有组件,但是我可以在这样的粒度级别上进行吗?
编辑
根据MSDN中的注释,我将属性更改为以下内容,但仍然无效.
[assembly: InternalsVisibleTo( "B, " + …Run Code Online (Sandbox Code Playgroud) 我有一个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()
{
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我打算C++通过这种方式调用这个dll .
[DllImport("CalculationC.dll",EntryPoint="Calculate", CallingConvention=CallingConvention::ThisCall)]
extern void Calculate();
[DllImport("CalculationC.dll",EntryPoint="GetResult", CallingConvention=CallingConvention::ThisCall)]
extern int GetResult(int arg1, int arg2);
Run Code Online (Sandbox Code Playgroud)
这是函数,其中称为GetResult
private: System::Void CalculateResult(int arg1, int arg2)
{
int …Run Code Online (Sandbox Code Playgroud) 我在C++/CLI程序集中有一个托管对象.作为C++/CLI,它通过"析构函数"实现Disposable模式(是的,我知道它与标准C++析构函数不同).从C++/CLI,我只是delete对象.但是,我将此对象用作C#类中的成员变量.
从我的C#类开始,当我使用它时,我想调用C++/CLI对象上的Dispose()方法的等效方法.由于它是(并且必须是)类的成员变量,因此使用using()块是不可能的.据我所知,没有公开的方法可以直接,确定地处理来自C++/CLI之外的语言的资源.我怎么能做到这一点?
我有一个真正的机器人,正在开放我的虚拟机器人.我希望在线显示我的主机器人(真正的机器人)在奴隶(虚拟的一个在开放的gl)中的每一个动作,所以我需要连续更新我的过剩窗口,实际上只要真正的机器人移动我的虚拟移动也是如此,所有这些运动应该在线.
我总是使用get data函数从master获取数据,但我不知道应该如何更新窗口.
这是我的代码:
******************************************** /
void OnIdle(void){
initSocket();
printf("\n Defining Step Time Parameters and Initial Conditions for solving Dynamic equations\n");
xi=0;
xf=0.1;
printf("\n end value x : %f ",xf);
i=0; yi[i]=0;
i++;yi[i]=-1.570796;
i++;yi[i]=-1.570796;
i++;yi[i]=0;
i++;yi[i]=0;
i++;yi[i]=0;
ndata=2; fi=1;
double counter=0.1;
Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
for(int i=0;i<50;i++)
//while(1)
{
getData();
printf("\n");
for(int i=0;i<6; i++)
{
printf("%d …Run Code Online (Sandbox Code Playgroud) 我有一个项目,其中包括一些性能敏感的本机C++标头,大量使用模板.对于这个项目,我们还包装头文件并添加一些粘合代码以向c#和其他.NET语言公开功能.我们将此标题称为"layout.h",我们将假设它是第三方标题,我无法更改.
在混合模式C++/CLI程序集中,从#pragma unmanaged(或#pramga managed(push,off))代码中的某个位置出错并#include相对容易.当发生这种情况时,模板会生成IL,并且在运行代码时会获得额外的托管/非托管转换,并且性能会下降.
我的问题是,是否有一种方法可以在#include之前进行编译时检查,以便编译失败,如果我意外地从错误的上下文#including.
// File1.cpp, compiled in a mixed mode C++/CLI assembly with /clr
ASSERT_UNMANAGED()
#include <layout.h>
Run Code Online (Sandbox Code Playgroud)
我天真的第一次尝试检查了#ifdef _MANAGED,但总是定义我是否在#pragma非托管代码块中.
我只是想知道为什么有两种方法来指定空指针.我一直在浏览这个链接,但没有清楚地了解它的用途.
有人可以举出什么时候使用什么的好例子吗?
我正在使用一个streamwriter与后台工作者一起进行日志记录.
就这样,我有
System::Void
MyUI::execBWorker_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
String^ outputPath = _clr::Settings::ApplicationLogPath("_log.txt", true, false);
logfile_ = gcnew StreamWriter(outputPath,true);
DoStuff();
logfile_->Close();
}
Run Code Online (Sandbox Code Playgroud)
DoStuff()方法中的内容引发了Progress事件.
System::Void
MyUI::execBWorker_ProgressChanged(System::Object^ sender, System::ComponentModel::ProgressChangedEventArgs^ e) {
logfile_->WriteLine("something");
}
Run Code Online (Sandbox Code Playgroud)
我觉得这真的很有气味.我怎样才能让它变得更好,或者至少如何检查日志文件是否尚未关闭?有很多消息,所以我担心连续打开和关闭日志文件.
我正在用C#编写一个GUI工具来解析和显示用C编写的另一个程序的数据输出.为了解析数据,我需要知道在多个C头文件中指定的数据结构.因此,我需要将这些C头文件合并到我的C#项目中.我的问题是:
1)经过一些研究后我得出结论,最好的方法是在我的解决方案中创建一个新的C++/CLI项目,将C头文件导入到这个新项目中,编写一些C++/CLI类作为数据的薄包装器在C头文件中定义的结构,然后从C#代码引用C++/CLI包装器类.这是最好的方法,还是有更好的方法?
2)我遇到了参考问题.这是我的简化代码来说明问题:
C++/CLI项目中的原始C头
#define ABC 0x12345
Run Code Online (Sandbox Code Playgroud)
C++/CLI项目中的包装类
#include "my_c_header.h"
namespace C_Wrappers {
public ref class MyWrapper {
public:
property unsigned int C_ABC {
unsigned int get() { return ABC; }
}
}
}
Run Code Online (Sandbox Code Playgroud)
C#项目中的用户类
using C_Wrappers;
using System;
namespace DataViewer {
public partial class MainForm : Form {
private MyWrapper myWrapper = new MyWrapper();
public MainForm() {
Console.WriteLine(myWrapper.C_ABC.ToString());
}
}
}
Run Code Online (Sandbox Code Playgroud)
在C#项目中,我添加了对C++/CLI项目的引用(使用右键单击>添加引用).在构建期间,我在C#项目中遇到错误:"找不到类型或命名空间'C_Wrappers'(你是否缺少using指令或程序集引用?)."
我以为我做了我应该做的一切.我该怎么做才能解决这个错误?
c++-cli ×10
c# ×4
.net ×2
c++ ×2
interop ×2
c++11 ×1
clr ×1
dependencies ×1
dll ×1
dllimport ×1
glut ×1
loops ×1
opengl ×1
streamwriter ×1
visual-c++ ×1