我需要使用C++/CLI(数组)将本机(即非托管)数据(byte*)复制到托管字节数组.
我试过Marshal :: Copy(数据由const void*data指向,是dataSize字节)
array<byte>^ _Data=gcnew array<byte>(dataSize);
System::Runtime::InteropServices::Marshal::Copy((byte*)data, _Data, 0, dataSize);
Run Code Online (Sandbox Code Playgroud)
这给出了错误C2665:16个重载中没有一个可以转换所有参数.然后我试了一下
System::Runtime::InteropServices::Marshal::Copy(new IntPtr(data), _Data, 0, dataSize);
Run Code Online (Sandbox Code Playgroud)
产生错误C2664:参数1无法从"const void*"转换为"__w64 int".
那怎么可能呢?Marshal :: Copy确实是"最好的"(最简单/最快)的方式吗?
如何将从表单/控件的Handle属性获取的句柄转换为IWin32Window ^?
我是Windows开发人员,我正在使用Microsoft visual studio 2008 SP1.我的开发者机器是64位.
我目前正在处理的软件是用C#编写的.exe文件.不幸的是,我无法仅在C#中解决整个问题.这就是我在C++/CLI中开发了一个小型托管DLL的原因.两个项目都在同一个解决方案中.
我的C#.exe构建目标是"任何CPU".当我的C++ DLL构建目标是"x86"时,不加载DLL.据我所知,当我用Google搜索时,原因是C++/CLI语言与其他.NET语言不同,它编译为本机代码,而不是托管代码.
我将C++ DLL构建目标切换到x64,现在一切正常.但是,一旦我的客户端将我的产品安装在32位操作系统上,AFAIK的所有内容都将停止工作.我必须支持Windows Vista和7,它们各自的32位和64位版本.
我不想回落到32位.我的DLL中的250行C++代码只占我代码库的2%.并且该DLL仅在几个地方使用,因此在典型的使用场景中它甚至都没有加载.
我的DLL用ATL实现了两个COM对象,所以我不能使用" / clr:safe "项目设置.
有没有办法来配置解决方案和项目,使C#项目建立"任何CPU"版本中,C++项目建立两个 32位和64位版本,然后在运行时管理.EXE启动时,它使用的是32 -bit DLL或64位DLL取决于操作系统?
或者也许有一些我不知道的更好的解决方案?
提前致谢!
如何在类声明之外放置托管类的静态构造函数体?这种语法似乎是可编译的,但它真的意味着静态构造函数,还是只是一个静态(=不可见的外部翻译单元)函数?
ref class Foo {
static Foo();
}
static Foo::Foo() {}
Run Code Online (Sandbox Code Playgroud) 从EventHandler委托的MSDN文档:
与C#和Visual Basic示例相比,Visual C++示例代码不要求您创建线程安全的临时变量.Visual C++版本自动提供线程安全访问,使您可以直接引发事件.
为什么C#不能自动提供对C++/CLI事件的线程安全访问?
这是我的问题.我在C#中包装一个C dll.为此,我首先编写了一个C++/CLI包装器.本机C库链接到C++/CLI包装器.(C++/cli项目中的链接器属性).
以下是它现在的组织方式: - 本机C .lib:x86和64bit.
我的问题来自于我需要C#来定位"任何CPU".但是此选项在C++/CLI中不可用,因为它直接编译为本机代码.
我想解决这个问题的方法是: - 在x86中编译C++/CLI包装器,然后更改配置并编译为64位.当它编译时,我想告诉它基于平台采取哪个dll.即:如果在64位编译,链接64位本机C dll,否则如果x86,链接x86本机C. - 完成后,我应该能够在我的C#平台中拥有任何CPU目标.在这里,我将不再引用我的C++/CLI包装器项目,而是基于目标平台引用所需的dll.
我的问题是:
让我补充一点,C#项目是一个由x86或x64客户端使用的CLASS LIBRARY.
我希望我的问题很清楚.任何帮助将不胜感激!
UPDATE基于:.NET项目中的条件引用,有可能摆脱警告吗?...
所以现在我使用条件编辑我的.csproj文件来引用dll,如下所示:
<ItemGroup>
<Reference Include="AlibCppWrapper, Version=1.0.4303.21410, Culture=neutral, PublicKeyToken=c0c17a53adc44091, processorArchitecture=AMD64"
Condition="$(Platform) == 'x64'">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\x64\Debug\AlibCppWrapper.dll</HintPath>
</Reference>
<Reference Include="AlibCppWrapper, Version=1.0.4303.21410, Culture=neutral, PublicKeyToken=c0c17a53adc44091, processorArchitecture=x86"
Condition="$(Platform) == 'x86'">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Debug\AlibCppWrapper.dll</HintPath>
</Reference>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用,因为$(平台)设置为AnyCPU ...
有些语言允许您将常量与接口相关联:
W3C抽象接口也是如此,例如:
// Introduced in DOM Level 2:
interface CSSValue {
// UnitTypes
const unsigned short CSS_INHERIT = 0;
const unsigned short CSS_PRIMITIVE_VALUE = 1;
const unsigned short CSS_VALUE_LIST = 2;
const unsigned short CSS_CUSTOM = 3;
attribute DOMString cssText;
attribute unsigned short cssValueType;
};
Run Code Online (Sandbox Code Playgroud)
我想定义这个接口,以便可以从C#调用它.
显然,C#无法定义与接口关联的常量.
SQLGetDiagRec返回本机错误代码.是否有任何概述SQL Server 2012的错误代码?我在MSDN上找不到任何东西.
我们有一个大型的.NET解决方案,其中包含相互引用的C#和C++/CLI项目.我们还有几个单元测试项目.我们最近从Visual Studio 2010和.NET 4.0升级到Visual Studio 4.5和.NET 4.5,现在当我们尝试运行单元测试时,在测试期间加载某些DLL似乎存在问题.
问题似乎发生,因为单元测试是在单独的AppDomain上执行的.单元测试过程(例如nunit-agent.exe)创建一个新的AppDomain,AppBase设置为测试项目的位置,但是根据Fusion Log,一些DLL加载了nunit的可执行文件目录作为AppBase而不是AppDomain的AppBase .
我设法用一个更简单的场景重现问题,它创建了一个新的AppDomain并尝试在那里运行测试.这是它的外观(我更改了单元测试类的名称,方法和dll的位置以保护无辜者):
class Program
{
static void Main(string[] args)
{
var setup = new AppDomainSetup {
ApplicationBase = "C:\\DirectoryOfMyUnitTestDll\\"
};
AppDomain domain = AppDomain.CreateDomain("MyDomain", null, setup);
ObjectHandle handle = Activator.CreateInstanceFrom(domain, typeof(TestRunner).Assembly.CodeBase, typeof(TestRunner).FullName);
TestRunner runner = (TestRunner)handle.Unwrap();
runner.Run();
AppDomain.Unload(domain);
}
}
public class TestRunner : MarshalByRefObject
{
public void Run()
{
try
{
HtmlTransformerUnitTest test = new HtmlTransformerUnitTest();
test.SetUp();
test.Transform_HttpEquiv_Refresh_Timeout();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试执行单元测试时遇到的异常.正如您所看到的,问题发生在C++ dll初始化并尝试加载C#dll(我将所涉及的DLL的名称更改为CPlusPlusDll和CSharpDll):
System.TypeInitializationException: …
据我所知,我可以使用反向P/Invoke从C++调用C#.反向P/Invoke只是一个例子:
问题:
提前致谢