两台机器..NET 3.5和VS 2008 VC++ SP1可再发行组件都有
一个使用两个签名DLL的exe,一个在C++/CLI中,另一个在C#中
exe在一台机器上加载并运行良好.
另一方面,我在C++可执行文件中得到"强名称验证失败"(HRESULT 0x8013141A)
有任何想法吗?
如何将函数指针从托管C++(C++/CLI)传递给非托管方法?我读了一些文章,比如MSDN中的这篇文章,但它描述了两个不同的程序集,而我只想要一个.
这是我的代码:
1)标题(MyInterop.ManagedCppLib.h):
#pragma once
using namespace System;
namespace MyInterop { namespace ManagedCppLib {
public ref class MyManagedClass
{
public:
void DoSomething();
};
}}
Run Code Online (Sandbox Code Playgroud)
2)CPP代码(MyInterop.ManagedCppLib.cpp)
#include "stdafx.h"
#include "MyInterop.ManagedCppLib.h"
#pragma unmanaged
void UnmanagedMethod(int a, int b, void (*sum)(const int))
{
int result = a + b;
sum(result);
}
#pragma managed
void MyInterop::ManagedCppLib::MyManagedClass::DoSomething()
{
System::Console::WriteLine("hello from managed C++");
UnmanagedMethod(3, 7, /* ANY IDEA??? */);
}
Run Code Online (Sandbox Code Playgroud)
我尝试创建我的托管委托,然后我尝试使用Marshal::GetFunctionPointerForDelegate方法,但我无法编译.
我需要从本机C++应用程序连接到WCF服务.我尝试了下面的链接并且它可以使用wsHttpBinding.
但是,我需要使用自定义绑定连接到WCF服务.这就是我的应用程序配置文件中自定义绑定的代码的样子
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="ResourceCenterEndpoint5">
<mtomMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Default" maxBufferSize="65536" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</mtomMessageEncoding>
<httpTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Ntlm"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536"
proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
</binding>
</bindings>
<client>
<endpoint address="http://usaabcxyzas1.na.abc.com/Build15/ReserSVC/Resource.svc"
binding="customBinding" bindingConfiguration="ResourceCenterEndpoint5"
contract="ServiceReference2.ResourceCenterServiceContract"
name="ResourceCenterEndpoint5">
<identity>
<userPrincipalName value="devlts_srv@na.abc.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Run Code Online (Sandbox Code Playgroud)
我有一个桥DLL,它是一个托管C++ DLL.托管C++ DLL将C#Client连接到本机应用程序.但是,由于Web服务使用自定义绑定,因此无法从托管C++ DLL连接到Web Service.我得到的错误是:
使用客户端身份验证方案"匿名"未授权http请求.从服务器收到的身份验证标头是"Negotiate,NTLM"
这就是我尝试从manged C++ dll连接到Webservice的方法:
Binding^ binding = gcnew BasicHttpBinding();
EndpointAddress^ …Run Code Online (Sandbox Code Playgroud) 我一直在阅读这篇文章,以了解gcroot模板.我明白了
gcroot为垃圾收集堆提供句柄
然后
句柄本身不是垃圾收集.
我不明白的是以下内容:
当CLR对象与垃圾收集堆一起移动时,句柄将返回该对象的新地址.在将变量分配给gcroot模板之前,不必固定该变量.
这是否意味着即使存在引用该对象的gcroot句柄,垃圾收集器也会删除CLR对象?
它指的是什么是"新地址"?那么"变量在分配给gcroot模板之前不必固定"是什么意思?
我对一些C#库和控制台项目(但不是我从头创建的那些)有一个奇怪的问题,他们使用C++/CLI表示法显示手表和智能标签进行调试(例如,显示System::Object^我期望的位置System.Object) :

我已经尝试更改项目guids,因为我认为这是问题(有些已经改变),删除obj/debug文件夹,重新启动Visual Studio 2010,修复Visual Studio 2010甚至旧的收藏重新启动Windows.
是否有任何明显的设置我错过了以某种方式被启用?
我们的项目结构如,
native.dll: - 这包含用c\c ++编写的纯本机代码.这个native.dll使用*def文件公开了一些函数.
Wrapper Library(wrapper.dll compiled with .Net framework v4.0)-为了使用的功能native.dll,一个Wrapper lib(wrapper.dll)
是写在C++\CLI使用:clr\oldsyntax.此包装具有的所有代码Interoperability和Marshalling.
Application(Console App v4.0)直接用于wrapper.dll使用提供的功能native.dll.
现在这个项目需要在.Net Core中运行.这意味着我们将有一个
.Net Core application会reference wrapper.dll,反过来会参考
native.dll.
我知道这不会直接起作用.但问题是.Net Core(CoreCLR)是否支持 C++\CLI(clr\oldsyntax)运行时环境 ?
如果不是,该应用程序可能的解决方案是什么?
我有很多项目的大解决方案,使用VS2008 SP1,并且每天至少遇到一次LNK2022错误.如果我对解决方案进行全面重建,它可以很好地构建,但这并不好玩.
当依赖DLL"无意义地"更改时(即不更改任何方法或类),并且稍后构建引用项目时,就会发生这种情况.合并元数据时失败 - 无论这意味着什么.
首先要注意的是共享DLL是#using从多个.CPP文件引用的.
第二件事是,如果我从共享DLL中删除AssemblyInfo.cpp,那么问题就会消失(但我不确定这是否是一个合理的修复?).
我已尽可能地将其缩小到包含2个CLR类库项目的以下解决方案(xxx项目依赖于共享):
alt text http://i42.tinypic.com/jg2vds.png
以下是每个文件的内容:
public ref class Shared
{
};
Run Code Online (Sandbox Code Playgroud)
#pragma once
#using "Shared.dll"
public ref class Common
{
private:
Shared^ m_fred;
};
Run Code Online (Sandbox Code Playgroud)
#include "inc.h"
Run Code Online (Sandbox Code Playgroud)
要重现,首先要重建解决方案.它会建立好.
现在保存Shared.cpp并构建解决方案,它将构建正常并显示:
...
2>------ Build started: Project: xxx, Configuration: Debug Win32 ------
2>Inspecting 'd:\xxx\xxx\Debug\Shared.dll' changes ...
2>No significant changes found in 'd:\xxx\xxx\Debug\Shared.dll'.
2>xxx - 0 error(s), 0 warning(s)
========== Build: 2 succeeded, …Run Code Online (Sandbox Code Playgroud) 2012-12-09摘要:
我计划使用的实际CLR托管可执行文件与此问题中概述的非常类似,除了一些小的更改:
OPR_FinalizerRun根据Hans Passant的建议设置为某个值(当前为60秒,但可能会发生变化).CLRCreateInstance从mscoree.dll动态(以允许更好的错误消息没有安装兼容CLR时).Main程序集DLL中的指定函数.感谢所有花时间阅读问题和/或评论的人.
2012-12-02帖子底部更新.
我正在使用Visual Studio 2012和.NET 4进行混合模式C++/CLI应用程序,并且惊讶地发现某些本机全局对象的析构函数没有被调用.调查的问题,它原来,他们表现得像管理对象在解释这个职位.
我对此行为感到非常惊讶(我理解它对于托管对象)并且无法在任何地方找到它,无论是在C++/CLI标准中还是在析构函数和终结器的描述中.
根据Hans Passant的评论中的建议,我将程序编译为程序集DLL并将其托管在一个小的本机可执行文件中,这确实给了我所需的行为(析构函数有足够的时间来完成和运行在同一个线程中建造)!
我的问题:
ICLRPolicyManager->SetTimeout(OPR_ProcessExit, INFINITE)为可执行文件配置进程超时策略(即基本上调用)?这将是一个可接受的解决方法.要重现如下编译以下文件:
cl /EHa /MDd CLRHost.cpp
cl /EHa /MDd /c Native.cpp
cl /EHa /MDd /c /clr CLR.cpp
link /out:CLR.exe Native.obj CLR.obj
link /out:CLR.dll /DLL Native.obj CLR.obj
Run Code Online (Sandbox Code Playgroud)
不需要的行为:
C:\Temp\clrhost>clr.exe
[1210] …Run Code Online (Sandbox Code Playgroud) 我使用Visual Studio 2012作为C#和C++/CLI .dll的解决方案,C++/CLI dll引用本机.dll,例如boost.C++代码编译为x64.
当我打开VS时,我可以清理并构建我的项目.
使用测试资源管理器,我可以运行我的测试.
一旦我使用测试资源管理器运行测试一次,我就无法重建项目.似乎VS2012 Test Explorer对我的C++/CLI-dll保持锁定,并且在那里我收到以下错误:
LNK1104: cannot open file 'C:\Dev\LockExample\bin\Debug\cli.dll'
Run Code Online (Sandbox Code Playgroud)
因此,每当我使用Test Explorer运行测试时,我需要重新启动VS2012才能继续开发.显然,这不是一个可持续发展的过程.
测试和重建工作没有问题C#-only dll - 只要我能告诉问题只发生在使用本机x64代码的DLL上.
经过一些测试,我发现这里的反派是vstest.executionengine.exe.使用句柄(来自SysInternals),我看到vstest.executionengine.exe保存了.dll和cli-dll的.pdb的锁.对于托管专用dll,它没有任何锁定.
在测试运行完成后,如何让Visual Studio Test Explorer释放C++/Cli dll上的锁?
我有一个由三部分组成的库.首先是本机C++,它提供实际功能.其次是C++库的C++/CLI包装器/适配器,以简化C#到C++的转换.最后我有一个C#库,它通过C++/CLI适配器调用C++库.
现在我有两组并行枚举定义,一个存储在.cs文件中,另一个存储在.h文件中.这带来了双重问题:
c++-cli ×10
c# ×5
.net ×3
c++ ×2
.net-core ×1
assemblyinfo ×1
clr ×1
code-signing ×1
coreclr ×1
debugging ×1
delegates ×1
enums ×1
interop ×1
linker ×1
managed-c++ ×1
metadata ×1
mixed-mode ×1
unmanaged ×1
wcf ×1
windows ×1