具有静态变量的非托管静态库的托管C ++包装器挂起

时间:2010-10-26 20:42:59

标签: c++ static wrapper managed

问题的解释有点啰嗦,请耐心等待。

我有一个非托管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)];

2 个答案:

答案 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启动并运行后调用它。