问题的解释有点啰嗦,请耐心等待。
我有一个非托管C ++静态库,用于财务应用程序。它具有工作日约定,交换约定,债券约定等。大多数约定依赖于静态全局变量,这些变量在首次使用时初始化。该库还通过使用ODBC对SQL Server数据库运行一些查询来初始化启动时的假日日历。
我必须使用网络服务与第三方软件进行互动。现实的唯一方法是通过C#。这不是问题,我取得了很好的进展。但是,当我需要在C#中进行一些日期计算时,我遇到了绊脚石。由于我不想将所有C ++代码移植到C#,我认为实现这一目标的最有效方法是编写一个托管C ++类库DLL,它是我的非托管静态库的包装器。一切似乎工作正常,我没有编译时或链接时错误,我可以添加对包装器的引用,并查看所有正确的对象定义。但是,当我尝试运行我的应用程序时,它只是挂起。我试过玩一堆包装DLL的编译器设置,但无济于事。如果我删除了我的非托管库的项目依赖项,一切正常。我强烈怀疑我自由使用全局静态变量会导致问题。有没有办法解决这个问题,至少可以找出问题所在?示例代码如下。
谢谢, 马克。
// FSAManaged.h
#pragma once
using namespace System;
//class XLDate;
namespace FSAManaged {
public ref class Futures
{
public:
static DateTime Expiry(String ^ code, DateTime date);
};
}
实现甚至不依赖于对非托管静态库的依赖:
// This is the main DLL file.
#include "stdafx.h"
#include "FSAManaged.h"
namespace FSAManaged
{
DateTime Futures::Expiry(String ^ code, DateTime date) {
return DateTime::Today;
}
}
为了完整起见,这里是AssemblyInfo.cpp:
#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute("FSAManaged")];
[assembly:AssemblyDescriptionAttribute("")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("?????")];
[assembly:AssemblyProductAttribute("FSAManaged")];
[assembly:AssemblyCopyrightAttribute("??????")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
答案 0 :(得分:1)
使用调试器。如果你从C#然后Project + Properties,Debug中测试它,勾选“启用非托管代码调试”。强烈建议在Tools + Options,Debugging,Symbols中设置符号服务器。运行
挂起时使用Debug + Break All。 Debug + Windows + Threads并双击应该执行该作业的线程。调试+ Windows +调用堆栈以查看发生了什么。如果您无法弄明白,请在您的问题中发布堆栈跟踪。您在“输出”窗口和Visual Studio状态栏中看到的任何内容都是相关的。
答案 1 :(得分:0)
静态C ++变量从DllMain初始化。在DllMain中你不应该做很多事情;触发另一个Dll的负载是最重要的一个。如果你从DllMain打电话给其他人的图书馆,这很容易打破。
我建议您在Dll上创建一个Init函数,在dll启动并运行后调用它。