Hi Brian,
Oops, I forgot. It was written in VC++ 6.0 but I made a very minor
change to some logic in it recently and recompiled in VStudio 2003. Not
sure if that makes a difference, but though it was worth a mention.
I suspect it might, but I've never tried so I can't be sure. To be on
the safe side, I'd want to compile the C++ using the VS6 C++ IDE to
eliminate this as a potential cause, as this (I am assuming!) is how
the orginial author of the DLL compiled it?
The DLL itself does threading. Here's a quick overview of what it does:
I send an array to the DLL. The DLL hits a web page for each member of
the array and brings back the HTML. It parses the HTML, sticks it in a
database for my C# program to retrieve, then returns. For each web page
it hits and reads, it spawns a thread.
I doubt whether the threads that the DLL is spawning internally will be
an issue - this sounds fine so long as there are no obvious design or
implementation features that would be actively holding a thread. I
suspect that the blocking is more likely to be associated with how the
calls into the routine that loops your Array are being managed by the
clients of your DLL (i.e. your C# and COM wapper - see below).
I'm going to assume it was originally compiled multi-threaded. How can I tell?
I did searches on LIBC, LIBCMT, and MSVCRT and turned up nothing. I
don't see where in the IDE I can control the linker options - only how
to set them via the command-line, a command file, or via the ENV vars.
As far as I remember it's in the Project Setting in the VS6 C++ IDE.
It's been a while, but I think to use Win32 multithreading you need to
set the runtime library to "Multithreaded DLL".
I'm really not sure.
3 - How, where and by what is the C++ DLL being loaded? Which process
space is it running in? Does the model used allow multi threading or
multiple loading?
This is what I have to do to use it:
I register the DLL using regsrv32
In VStudio, I go under "Project -> Add Reference" and find it under the
COM tab - that may answer your previous question.
Yep 3 answers 2! My understanding from what you say is that your C++
DLL is COM compliant.
There is plenty on COM on MSDN if you're uncertain and want to know
more about it (try
www.microsoft.com/com). In case you're not aware,
COM (Component Object Model) is a framework that Microsoft introduced
to facilitate interoperability between software components without
those components knowing about each other's internals. COM allows you
to write components in different languages, and, so long as they are
COM-compliant, they can communicate with each other. You may have heard
of OLE and ActiveX? These are technologies within the COM umbrella
framework.
For your managed code (.NET C#) to interoperate with your COM DLL
(C++), a wrapper needs to be constructed which allows your C# to
communicate with your C++. Microsoft suggest using the Type Library
Importer tool to setup a .NET wrapper for a COM component that you wish
to call (see
http://msdn2.microsoft.com/en-US/library/ms173185(VS.80).aspx and
http://msdn2.microsoft.com/en-US/library/zeaxheha(VS.80).aspx for more
details). However, it may be the case that this is being run, and that
a wrapper is being created automatically for you, when you add the
reference to your project in the process you outline above. It's worth
checking that this done correctly!
I'm not sure how the wrappers created to allow you to call the COM
component work, so I don't know whether they will be synchronising
calls or not, preventing multiple loading or multithreading and so on.
Sorry I can't help anymore on this without researching it!
)
It uses a few mutexes, but only when it accesses specific web pages, and
the 2 that use mutexes I'm not using in my testing so that code never
gets called.
One other place it uses mutexes is in the error handler. If there's an
error, it writes it to a log and the mutex is there to stop file errors.
Umm, might be worth following the logic through as best you can to see
whether these are holding something up.
This is my first time with it. I'm not compiling the C++, I'm just
hooking into the DLL when my code runs. The DLL is already registered
in the system and waiting for something like my program to use it.
I don't think I gave you too many answers to your question, but
hopefully there's something there that may spark something. I
appreciate your help.
No problem!
As a suggestion, one way to see whether it's your COM, the COM wrapper
or the C# might be to use write a test ASP classic page to load the COM
DLL and kick off the same COM process. Again it's been a while, but
something like:
<%
Dim myComThingy
myComThingy = Server.CreateObject("MyLib.MyComponent")
myComThingy.DoTheLoopStuff(anArray)
%>
Then call into this ASP Classic page multiple times and see what
happens. You'll need to make sure that the Virtual Directory that the
ASP page is in on IIS is setup to put ASP into a COM+ process rather
than loading it into the IIS process space (set the application
protection to Medium (Pooled) in the Virt Dir properties in IIS5).
If the COM does it's job without holding synching the calls, then
you'll know the COM works and your issue is on the C# or COM wrapper
side. If not, then you know it's the COM.
Hope this helps, Mart.