COM calling convention on x64 - com

I am trying to get a definitive answer regarding the way COM behaves on a x64 machine. Does Windows use the normal x64 calling convention when dispatching calls to COM interfaces on x64 machines (assuming the COM implementation is 64 bits)? Specifically, I dynamically generate my vtbl entries to point to a chunk of assembly that's dynamically loaded during runtime. This assembly needs to know how to get parameters correctly from whomever is calling it. Thus, I'd like to know if COM sets up the call to my assembly using the standard x64 calling convention (pretty much fastcall).

The COM calling convention is whatever the STDMETHOD/STDMETHODIMP macros (and their variants) defines it to be. On IA-32, it's stdcall for most of them; I do not know what is used on x86-64 (I only have the 32-bit mingw cross-compiler installed).

Related

Determine which DLL and/or OCX files are actually used by my program?

My software is written in VB6. For diagnostic purposes I need to determine the actual DLL / OCX files which are loaded and used by the application on a customer's computer.
Since VB6 DLLs (including OCX files) are COM libraries they are loaded indirectly based on information in the registry. This means it is possible that a different file is being used than what was used in development / testing environments. Sometimes in a client environment this can cause malfunctions which are hard to diagnose without this information.
(My plan is to build a diagnostic readout window in my program that shows the libraries that the program is using at that moment.)
You can use the Dependency Walker to find which DLL your program depend on.
But the OCX are not so easy to find because they are loaded at run-time based on the application dependencies and the registered components through the Windows registry. But you have to already know which OCX components your application references - from the Tools > References and all the places you call CreateObject.
There are many ways in which runtime dependencies on DLLs (or OCX files) can be established. Ideally you would need to account for all of them:
This answer is specific to VB6 but many other programming languages would work similarly.
Mechanisms which establish runtime dependencies:
At Compile time for traditional dynamically-linked libraries (DLLs which are not COM)
Files are (as their name suggests) dynamically loaded at runtime based on the linking process done at the end of compilation
This includes VB6 code which has used a statement like: Declare Function … Lib …
(In .NET this would mean calling out into “native code”)
To identify: Inspect the source code.
To identify without sources: These can be detected by a tool like Dependency Walker
At Compile time for COM DLLs
In VB6 this is known as “early binding”.
This includes VB6 code which has explicitly set a reference to a DLL or OCX.
Note that the dependency is actually on the COM class or interface GUID, and not explicitly on the DLL file itself.
To identify: These are listed in the project VBP.
To identify (alternate): If you don't have the VBP or source code, these dependencies can generally be revealed by by IMPORT statements in OLEView. You might need to look up some GUIDs from there in the registry to see what actual DLL files are used.
At Compile time for statically-linked libraries (not COM, not DLLs)
Library code is included in the EXE or DLL which is being compiled. Therefore there is no runtime dependency to anything external.
As far as I am aware, this is not possible for VB6 programs. Something like a C linker could use libraries like this. A rough equivalent in .NET would be using ILMerge to combine assemblies.
At Runtime for traditional DLLs (not COM)
DLLs can be loaded arbitrarily using Win32 API such as LoadLibrary().
To identify: You have to look at the source to know what might happen.
Alternately if you don't have the source you could use tools like Process Explorer and/or Process Monitor to observe a running instance and see what DLLs actually get loaded.
At Runtime for COM DLLs
Classes can be loaded arbitrarily using eg VB6 CreateObject() calls.
In VB6 this is known as “late binding”
Which DLL will be used to provide the class will be determined by the process’s activation context. The activation context is established by the app manifest file (if there is one) or the Windows registry otherwise (the normal default for VB6 programs).
To identify: You have to look at the source to know what might happen. You also need to know what the configuration state will be on the PC that runs the code - which DLL files are registered, assuming a manifest is not used.
Alternative for no source code: as in the case above
Important: dependencies can be chained. So really you need to "walk the links" of all the dependencies until you build up a complete mapping of what is required. Somewhere in that mapping you can draw a line between what you need to deploy and what the operating system or other runtime environment can be relied on to provide. (IMO for VB6, that line should be drawn rather liberally).
You may be thinking that all this makes the task very difficult or tedious – I totally agree. :)

Statically compile SQLite into a VB.Net application?

System.Data.SQLite (SDS) is apparently the most popular way to use SQLite from a .Net application.
I was wondering if
SDS requires shipping the SQLite DLL in addition, or if SDS includes
the SQLite source code, and
SDS can be statically compiled into a
VB.Net application of it can only be shipped as a DLL?
Thank you.
To expand on my comment, SDS is a .net wrapper for unmanaged code, so you will need to ship your release code with a copy of the DLL.
As Steve mentions, there are 32 and 64bit versions of the DLL, and as i discovered after much frustration, you must have the corresponding visual c++ runtime installed on the target machine, so if you deploy the 32bit version onto a 64bit machine, it will need the 32bit c++ runtime environment installed.
An alternative that i am currently looking into but havent had time to test is csharpe-sqlite, a pure .net implementation:
http://code.google.com/p/csharp-sqlite/
Coded in c# as the name suggests, but of course usable in any .net language including vb.net
Actually it's quite easy to compile System.Data.SQLite.dll to the does not require C++ runtime. For example if you download source code and follow the build procedures you'll find statically linked (no C/C++ runtime required) copy of System.Data.SQLite.dll in the following path:
<your-src-root>\bin\<2008 or 2010>\<Win32 or x64>\ReleaseStatic
For example if your source is in C:\Work\sqlite-netFx-source-1.0.80.0 then statically linked binary for Win32 and .NET 3.5 (VS 2008) will be located in:
C:\Work\sqlite-netFx-source-1.0.80.0\bin\2008\Win32\ReleaseStatic
Furthermore since System.Data.SQLite.dll is a mixed-mode assembly consisting of a managed .netmodule and native .obj file linked together using link.exe, it is possible to build your app as a .netmodule as well and link it together with SQLite into a single mixed mode assembly.
The resulting assembly will still be either Win32 or x64, however since almost all x64 machines will have no problem running Win32 code you can just settle on Win32 as long as:
Your app is an .exe or a .dll the is always loaded into a Win32 process, and
You don't use any of x64 specific advantages such as larger address space or using unmanaged code available only in x64

LoadLibrary MSVCRT Issue

There are two questions that confuse me:
I read from the Microsoft website that we can not use different C runtime in the same project. Say I have a dll compiled with /MT flag, then I can not use the dll in a /MD compiled project. My question is that if I use LoadLibrary() to load the dll, is it also necessary that I have the same C Runtime? What's the potential danger if I don't?
I think with the /MT flag, the runtime is statically linked into the binary file. But for one of my dll project, I made a dll with /MT. However, when I dumpbin.exe /dependents mydll, it shows that MSVCR100.dll is a dependent. My question is that why the dll is still dependent on MSVCR100.dll?
1) No, that's not a requirement. This happens in any program, the Windows DLLs use their own CRT for example. Mixing CRTs in one program is however very dangerous and can cause very hard to diagnose problems. The Windows apis were carefully designed to avoid those problems, they never require code to release memory that was allocated in a DLL, don't use exceptions, don't use standard C++ library classes, don't depend on locale or any other kind of shared CRT state. The kind of things that go wrong when you mix. Restricting yourself to a C or COM api helps a lot to avoid these traps.
2) This will happen when you link code that was compiled with /MD. Common with .libs you link.
You stay out of trouble by always using /MD when you have DLLs in your project and compiling all code with the exact same compiler and options. Static libraries you didn't build yourself are very troublesome, avoid them.
Regarding your 2. question, the dependency is indirect. Your DLL uses a DLL which depends on MSVCR100.dll. Using Dependency walker you can see the dependency tree of your component and see which library is directly and indirectly dependent.

Generating .net assemblies for c++ modules

I am a .net developer who has never touched c++. I don't want to either :)
Unfortunately, I have to work with c++ module in .net 4.0 and I am clueless.
Is there a tool that can generate a .net assembly for a given c++ module?
If not, what are my next steps to successfully call these c++ libraries?
There are many ways:
COM Interop
Tlbimp.exe (Type Library Importer)
How to: Generate Primary Interop Assemblies Using Tlbimp.exe
The Type Library Importer converts the type definitions found within a COM type library into equivalent definitions in a common language runtime assembly.
PInvoke/DllImport
Calling Native Functions from Managed Code
The common language runtime provides Platform Invocation Services, or PInvoke, that enables managed code to call C-style functions in native dynamic-linked libraries (DLLs). The same data marshaling is used as for COM interoperability with the runtime and for the "It Just Works," or IJW, mechanism.
C++/CLI
Mixed (Native and Managed) Assemblies
How To: Migrate to /clr
This is more advanced because it will most probably require the C++ module to be updated and re-compiled.
Mixed assemblies are capable of containing both unmanaged machine instructions and MSIL instructions. This allows them to call and be called by .NET components, while retaining compatibility with components that are entirely unmanaged. Using mixed assemblies, developers can author applications using a mixture of managed and unmanaged functionality. This makes mixed assemblies ideal for migrating existing Visual C++ applications to the .NET Platform.

C++/CLI 64-bit COM

I have a C++/CLI assembly that wraps a native 32-bit dll.
The assembly is used both from .Net and COM (office).
Now I have a customer that runs 64-bit office.
Is it possible to create a C++/CLI assembly that uses a native 32-bit dll and exports a 64-bit com interface?
No, you can't mix code with different bitness in one process on Windows. You need to force 32-bit code into a separate process or convert that DLL.
The latter can likely be achieved by using COM+ (or DCOM which is mostly the same). This is what we usually do with native C++ code. I'm not sure about how easy it is with C++/CLI assemblies.
In a manner of speaking, yes.
Continue to compile the C++/CLI code as 32-bit so it can use the native library using C++ interop.
Then you will have to configure it to load as an out-of-process COM server when acting as an Office 64 plugin. With native COM code, midl automatically generates the 64-bit proxy. There should be some similar capability to create a proxy when registering .NET classes marked COMVisible.
The 64-bit COM interface will be contained in the auto-generated 64-bit proxy DLL, so this doesn't violate the rule that the bitness of all modules in a process must be the same.