小编Kad*_*ura的帖子

为什么Cdecl调用在"标准"P/Invoke公约中经常不匹配?

我正在开发一个相当大的代码库,其中C++函数是从C#调用P /.

我们的代码库中有很多调用,比如......

C++:

extern "C" int __stdcall InvokedFunction(int);
Run Code Online (Sandbox Code Playgroud)

使用相应的C#:

[DllImport("CPlusPlus.dll", ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
    private static extern int InvokedFunction(IntPtr intArg);
Run Code Online (Sandbox Code Playgroud)

我已经搜索了网(在我有能力的范围内),因为为什么存在这种明显的不匹配.例如,为什么C#中有Cdecl,而C++中有__stdcall?显然,这会导致堆栈被清除两次,但是,在这两种情况下,变量都以相同的相反顺序被压入堆栈,这样我就不会看到任何错误,尽管在发生的情况下可能会清除返回信息.在调试期间尝试跟踪?

来自MSDN:http: //msdn.microsoft.com/en-us/library/2x8kf7zx%28v=vs.100%29.aspx

// explicit DLLImport needed here to use P/Invoke marshalling
[DllImport("msvcrt.dll", EntryPoint = "printf", CallingConvention = CallingConvention::Cdecl,  CharSet = CharSet::Ansi)]

// Implicit DLLImport specifying calling convention
extern "C" int __stdcall MessageBeep(int);
Run Code Online (Sandbox Code Playgroud)

再一次,extern "C"C++代码和CallingConvention.CdeclC#中都有.为什么不CallingConvention.Stdcall呢?或者,此外,为什么__stdcallC++中存在?

提前致谢!

c# c++ pinvoke cdecl stdcall

53
推荐指数
2
解决办法
2万
查看次数

在64位(或32位)Windows上以32位进程访问> 2,3,4GB文件

免责声明:我为这个问题的冗长而道歉(我认为这是一个有趣的问题!),但我无法弄清楚如何更简洁地说出来.

我已经做了几个小时的研究,以解决在64位Windows 7(从AWE /LARGEADDRESSAWAREVirtualAllocExAWE)上以32位进程访问多GB文件的问题.我在Windows中编写一个多视图内存映射系统(CreateFileMapping,MapViewOfFile等)时有点舒服,但是不能完全摆脱对这个问题有一个更优雅的解决方案的感觉.此外,我非常了解Boost的进程间和iostream模板,虽然它们看起来相当轻巧,只需要花费相同的努力来编写仅使用Windows API调用的系统(更不用说我已经有了一个内存 - 使用Windows API调用半实现的映射体系结构).

我正在尝试处理大型数据集.该程序依赖于预编译的32位库,这就是为什么目前程序本身也在32位进程中运行,即使系统是64位,64位操作系统.我知道有一些方法可以在其中添加包装库,但是,看到它是更大的代码库的一部分,它确实是一项任务.我设置二进制头是允许的/LARGEADDRESSAWARE(以减少我的内核空间为代价?),这样我每个进程可以获得大约2-3 GB的可寻址内存,给予或接受(取决于堆碎片等).

问题在于:数据集为4 + GB,并且运行DSP算法,需要对文件进行基本随机访问.指向从文件生成的对象的指针在C#中处理,但文件本身在C++中加载到内存中(使用此部分内存映射系统)(它是P/Invoked).因此,我认为解决方案不仅仅是简单地调整窗口来访问我需要访问的文件部分,因为本质上我仍然希望将整个文件抽象为单个指针,我可以从中调用方法几乎在文件中的任何位置访问数据.

显然,大多数内存映射架构依赖于将单个进程拆分为多个进程.因此,例如,我将访问具有3个进程的6 GB文件,每个进程持有2 GB的文件窗口.然后,我需要添加大量逻辑来从这些不同的窗口/进程中提取和重新组合数据. VirtualAllocEx显然提供了一种增加虚拟地址空间的方法,但我仍然不能完全确定这是否是最好的方法.

但是,让我们说我希望这个程序在64位系统上像64bit进程一样"轻松"运行.假设我不关心颠簸,我只是想能够操作系统上的大文件,即使在任何时候只有500 MB被加载到物理RAM中.有没有办法获得这个功能,而无需手工编写一个有点荒谬的手动内存系统?或者,有没有比我通过梳理SO和互联网找到的更好的方式?

这有助于提出一个第二个问题:有没有办法限制这个过程使用多少物理RAM?例如,如果我想将进程限制为在任何时候只将500 MB加载到物理RAM中(同时将多GB文件保留在磁盘上),该怎么办?

对于这个冗长的问题,我感到很遗憾,但我觉得这是一个很好的总结,看起来很多问题(只有部分答案)我已经在SO和网络上找到了.我希望这可以成为一个可以充实明确答案(或者至少是一些优点/缺点)的领域,我们都可以在这个过程中学到有价值的东西!

c++ windows memory-management out-of-memory memory-mapped-files

6
推荐指数
1
解决办法
764
查看次数

禁止作为mt.exe构建后事件的结果的GUID警告

在一个大的,预先存在的代码库中,我有几个*.dll,我需要注册COM interop.

这些清单注册使用mt.exe以下列方式作为构建后事件执行:

mt.exe -manifest "$(ProjectDir)myProjectManifestFragment.xml" -nodependency -managedassemblyname:"$(TargetFileName)" -out:"$(TargetName).manifest" -outputresource:"$(TargetFileName)";#2
Run Code Online (Sandbox Code Playgroud)

在这种情况下,不需要显式GUID,但是,自然地,mt.exe会生成以下性质的混乱警告:

mt.exe : genman warning G81010014: Explicit guid not defined for type myInternalType
Run Code Online (Sandbox Code Playgroud)

我的问题是:如何在不明确定义GUID的情况下抑制这些警告?

注意,我不想采用post-build事件并重定向输出(la> NUL),因为我仍然希望收到错误通知.有一种方法只能从mt.exe中抑制stderrs,但我只想抑制这个警告.我甚至很高兴抑制mt.exe生成的所有警告(具体不必是G81010014).

mt.exe在MSDN上的文档似乎只显示一个详细的标志,但没有办法将详细级别更改为"简洁"模式,其中警告将被抑制.在Visual Studio 2010中,显然有一种方法可以抑制特定警告,但我无法确定这如何适用于特定于构建后事件,更不用说仅由mt.exe生成的警告.

先感谢您!这实际上是我在Stack Overflow上的第一篇文章:)让我知道我是否需要更具体,更广泛等... ^ _ ^

干杯!

-Kadaj

c# guid suppress-warnings post-build-event visual-studio

5
推荐指数
1
解决办法
613
查看次数

DLL在VS2010中缺少模块列表

我真的一直在抨击这个谚语墙.

我有一个包含C#和C++代码项目的解决方案.

我经常调用C++ DLL,它们是在C#中通过P/Invoke在这个项目中编译的.没问题.据*.sln我所知,通过文件以及C++和C#文件的所有必需调试器设置都已正确设置.注意:我经常能够调试类似的P/Invoked C++代码而没有任何问题!

当然,我想,也许,符号没有加载 - 但是,在打开模块窗口时,我发现我试图步入的DLL甚至没有列出!跑在我的C#程序确实使用DLL(我得到正确的输出)功能,但是,同时观看模块窗口中,DLL仍然没有出现.

有没有人知道发生了什么?


TL;博士

我在调试P/Invoked C++方面有相当多的经验.但是,我想调试的DLL甚至没有出现在Modules列表中(所以如果VS调试器似乎完全没有意识到它的存在,我显然无法进入它).

c# c++ pinvoke visual-studio-2010 visual-studio-debugging

5
推荐指数
1
解决办法
2591
查看次数