I'm reading msdn pages introducing DLLs in C++, in both Regular DLLs Statically Linked to MFC and Regular DLLs Dynamically Linked to MFC, it says:
Regular DLLs must have a CWinApp-derived class and a single object of
that application class, as does an MFC application. However, the
CWinApp object of the DLL does not have a main message pump, as does
the CWinApp object of an application.
Is this true?
I'm actually using XLW (an open source application that wraps the Excel C API in simple C++ interfaces ) to build XLL plug-ins for Excel.
Howcome I couldn't find any CWinApp in either the codes generated by XLW or the XLW source code?
ps: Notes on XLW -- basically, if you write a library consists of mylib.h and mylib.cpp, XLW will parse mylib.h and generate xlwmylib.cpp; compile and link all three files together, will generate a mylib.xll, that can be imported by Excel as an add-in; then Excel can call functions defined in mylib.h as normal Excel function, either in formular or in VBA.
Related
Can a Portable Class Library be referenced from a VBA context such as Excel? I tried adding a reference to the DLL but it fails with "Can't add a reference to the specified file."
I have written a normal class library before (with its build settings set to expose to COM) that references a PCL and then provides wrapper methods. This is tedious and complicated, is there a better solution that would expose the PCL as-is?
Here is scenario:
I have a VB6 project. It contains a method which receives parameter of type variant by ref.
Function GetFilledInfo(data As Variant)
This method fills the received parameter with a structure. This structure is defined in my VB6 project as follows.
Public Type DATASTRUCTMAIN
structChild As DATASTRUCTCHILD
End Type
Public Type DATASTRUCTCHILD
m_bComputeRanges As Long
End Type
I have a C# program which calls this method by referring the ActiveX dll generated by VB6 project.
I want to declare structure that is defined in VB6 inside my C# program and want to get it filled by using VB6 method.
How can I do this?
Thanks in advance.
I can't help noticing that you are only passing a Long (unless you have truncated those structure definitions for brevity). In that case, just change the VB6 so that it exposes a function that returns a Long!
If you have a real structure...
Move the structure definition to a public class in your VB6 project. Then the structure definition will become publicly available through COM for any clients who reference your VB6 project.
Hopefully you will be able to use it in your C# project and you will be able to declare instances of the structure. You do have a reference to the VB6 component in the Project References in your C# project, right? Not too familiar with .Net COM interop, so not sure about this.
If you have any problems declaring instances of the structure in your C# project, you could change the VB6 structure into a class? Apparently structures can be problematic in COM interop
I am trying to evaluate Excel DNA to use it in one of my excel add-in. I use C# functions (.NET 4.0) and want to invoke these functions from Excel. The reason I am interested is, the users of my addin are non-admins and hence would be a breakthrough, if I can find a solution not to do a regasm on my .NET dll, to get my addin working.
I understand that if it is like a worksheet function (with simple return types and arguments), as in: private string Add (int a, double b)
I can easily wrap expose them using excel dna. Also, I understand that, I can also call these simple functions using Application.Run from VBA.
But, if I have a complex type involved in the API and want to use this from VBA then do I require to regasm that assembly and types? example as in this:
private MyType AddLogic (myType1 A, myType2 B)
Or is there any way in Excel DNA, that I can also consume such kinds of functions in VBA without any regasm or regsvr32 ?
Thanks
Mani
You are referring to the built-in COM server support in Excel-DNA. There are a few options, all of them work fine for users without administrator rights.
You can register the COM types at runtime in your AutoOpen - they will then be available late-bound from VBA (so everything in VBA calling those COM types will be 'Variant' and you get no intellisense).
You can register the COM types with regsvr32, using the .xll as your COM server. The Excel-DNA registers its types in the HKEY_LOCAL_USER part of the registry, which the user can always write to.Then the VBA project that uses the COM-exposed types will run even if the .xll add-in is not loaded.
To add type library information for the COM-exposed types, you will have to do the regsvr32 registration, which again works without admin rights, and then you get intellisense etc. in VBA.
In none of these cases do you use RegAsm - which registers managed assemblies for runtime activation - since the native Excel-DNA .xll mediates the COM activation of your .NET types itself.
If you are not interested in providing worksheet functions, ribbons etc. you probably don't need Excel-DNA for this. You can register .NET assemblies for use by non-admin from VBA by just making a .reg script which will right the registry entries in HKEY_LOCAL_USER instead of HKEY_CLASSES_ROOT. I mean to say that the non-admin registration of Excel-DNA is no special magic. The main reason for integration of this feature in Excel-DNA is to ensure that those objects are activated in the same AppDomain as the rest of the Excel-DNA add-in, which is tricky and sometimes important.
How can I share source code between 2 projects in MS Visual Studio 2008 (I'm programming in C++)?
In my case, I have the code for the main game project and now I want to make a simple model editor that uses the game's code, so that whenever I change/add some code in one project it will be updated in the second one.
A common method for doing this, (you'll see it everywhere in open-source packages), is to bundle all the headers into an 'include' folder and all the source into a 'source' folder.
Now in whatever project needs the code, you go to, 'Project Properties->c/c++->General->Additional Include Directories'. Then add the path to the 'include' directory. Finally, add the source/headers to your project, now both projects reference the exact same files, which are in a nice tidy shared location.
You can also build the shared code as a static library or better yet (IMO) a DLL. This involves creating a new project, and learning a little bit about the linker in VS 2008, but really nothing too complicated. This also has the advantage (in the case of a DLL) that the two projects don't re-compile the same code, but rather it is compiled once and used twice.
You can move the required classes into a separate library project and then references this from the second project. Any changes will be automatically picked up.
(I'm not a C++ developer, however the above works for C# projects, I would assume it works for C++ projects too)
You basically have two options:
Create a static library. In this, all the code in the library will be exported and visible to who ever links to this library.
Create a DLL: here, you can define what classes and methods you would like to export and use those.
Lets say you have a class called classA which is defined in classA.h and implemented in classA.cpp and you want to use this same class from two different applications (application B and application C).
Using method 1, you would create a static library by going to file->new win32 project and in the box that pops up, choose application settings and make it a "Static Library". Then in this static library you add both your classA.h and classA.cpp.
To use this static library in application B or C, goto the references and add a reference to the static library project that you just created. then include classA.h in your application (don't forget to set the additional include directories path) and you are good to go.
The approach is very similar for a DLL as well, the difference here would be that you can choose what parts of your code in the DLL are exported (ie visible to outside callers).
From an overall point of view:
With the static library approach, your code will be compiled into both the applications.
With the DLL approach, there will be just one copy of the shared code (in the DLL which will be a separate file) and this will be loaded as required.
When creating a DLL with Visual C++ 2008 I have a couple of choices. I can create a "Class Library", which I understand will actually give me a .Net Library that uses the CLI (managed) extenstion of C++.
Since I don't want that, and I assumed that I need a static .LIB file to link into another Visual C++ windows executable project, I choose instead "Win32 Project" and, on the Application Settings panel, specify a C++ (no MFC) DLL.
This will create a project with a .cpp file which is supposed to be where I define "the exported functions for the DLL application".
This doesn't seem to be what I want either. Basically, what I'm looking for is the native C++ equivalent of what would, in C# .NET be a class library assembly. I want to package some classes into a DLL, then have a .EXE project use the DLL's classes by including the DLL project header files and link with a .LIB to resolve references.
What's the usual way of doing this?
You're doing it right. What you'll need is to mark your classes with __declspec(dllexport) to make them available from outside the project. When you build the project, you'll generate both a .DLL and a .LIB.
Create a new Project
Visual C++ : Win32 : Win32 Project
Application Settings select DLL and check 'Export Symbols"
When you generate the project, it will stub out an exported class for you, typically named C{MyLib}.
You are right to make a C++ (no MFC) DLL. You can create your classes and those entry points which you define will be exported from that DLL for use by other C++ code (for example, a Win32 application written in C++).
Since C++ names get mangled automatically by the compiler to weird and wonderful values, it's not practical to export them as is if the DLL's clients are, for example, C programs. But if everything is in C++, you should be OK.
If you create some classes, you can choose to have them linked dynamically (as a DLL) but you will need an import library (created for you automatically) which contains the DLL's symbol definitions. You can also choose to link statically to your code from an application - in this case you would end up with a static library (also a .LIB) which contains the actual object code in your classes rather than symbols in a DLL.
The advantage of a DLL is, of course, that if you write several applications using your library, they can all share the DLL; with a static library, they would each contain a copy of your library code.
I think this article describes what you are trying to do:
http://www.codeproject.com/KB/mcpp/usingcppdll.aspx
Personally I also prefer exporting C functions (as opposed to C++) where I make the this pointer explicit to avoid having to care about compiler specific method name decoration and exposing compiler generated functions.