开发者

Managed C++ Wrapper for Unmanaged Static Library with static variables hangs

The explanation of the problem is a little long-winded, please bear with me.

I have an unmanaged C++ static library that is used for financial application. It has business day conventions, swap conventions, bond conventions, etc. Most of the conventions rely on static global variables, which are initialized on first use. The library also initializes the holiday calendars on startup by running some queries against a SQL Server database using ODBC.

I have to interact with third-party software using web services. The only way to do this realistically is through C#. That isn't an issue, and I was making good progress. However, I hit a stumbling block when it became necessary to do some date calculations in C#. Since I didn't want to port all my C++ code to C#, I figured the most efficient way to achieve this would be by writing a Managed C++ Class Library DLL that is a wrapper around my unmanaged static library. Everything seems to work fine, I get no compile-time or link-time errors, and I can add the reference to the wrapper and see all the proper object definitions. However, when I try to run my application, it just hangs. I have tried playing around with a bunch of compiler setting for the wrapper DLL, to no avail. If I remove the project dependency on my unmanaged library, everything works fine. I have a strong suspicion that my liberal use of global static variables is causing issues. Is there are way to solve this problem, are at least figure out where the issue is? Example code is below.

Thanks, Marc.

// FSAManaged.h

#pragma once

using namespace System;

//class XLDate;

namespace FSAManaged {
 public ref class Futures
 {
 public:
  static DateTime Expiry(String ^ code, DateTime date);
 };
}

The implementation does not even rely on a dependency to the unmanaged static library:

// This is the main DLL file.
#include "stdafx.h"
#include "FSAManaged.h"


namespace FSAManaged
{
 DateTime Futures::Expiry(String ^ code, DateTime date) {
  return DateTime::Today;
 }
}

For completeness' sake, here is 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:Assemb开发者_运维百科lyCultureAttribute("")];

//
// 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)];


Use the debugger. If you test this from C# then Project + Properties, Debug, tick "Enabled unmanaged code debugging". Setting up the symbol server in Tools + Options, Debugging, Symbols is strongly recommended. Run.

When it hangs use Debug + Break All. Debug + Windows + Threads and double-click the thread that is supposed to be doing the job. Debug + Windows + Call stack to see what is going on. Post the stack trace in your question if you can't figure it out. Anything you see in the Output window and the Visual Studio status bar is relevant too.


Static C++ variables are initialized from DllMain. There are lot's of things you should not do in DllMain; triggering the load of yet another Dll being the most important one. This is easy to break if you call into other peoples libraries in from DllMain.

I suggest you make an Init function on your Dll, which you call after the dll is up and running.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜