I am generate assembly object in memory and need to get it byte representation.
I've following code but today I need that it to be done in memory
var assembly = GetMyAssembly();
var binary = File.ReadAllBytes(assembly.Location);
I've looked into Assembly builder methods and Assembly methods but can't find appropriate methods.
Thanks.
I'm not sure about saving straight to a byte[], but you can save a dynamic assembly (defined using AssemblyBuilder), using AssemblyBuilder.Save, and then load it using File.ReadAllBytes. You can create it in a temporary directory, and delete it when you're done.
Hope that helps.
This is not possible in the runtime.
The only possible solution is to use WinDbg and SOS to dump the assembly. But then again, all my attempts at doing that exact same thing has failed.
Related
I have an application where I want to instantiate a class that is completely outside the application, perhaps written at a later date by a third party. So the class cannot be known, but the interfaces in the class are known. So I want to use late binding.
In my code (VB.NET), I have the following:
Dim a As Object
a = Activator.CreateInstance("MyNameSpace.CustomClass", "")
MsgBox(a.Name)
I get an exception at the second line: Could not load file or assembly 'MyNameSpace.CustomClass' or one of its dependencies. The system cannot find the file specified. even though the assembly is in the same folder as the executable. I can't use Type.GetType() because the type is not known to the calling assembly.
You need the CreateInstanceFrom method.
var typeReference = Activator.CreateInstanceFrom(assemblyPath,
fullyQualifiedClassName);
But, for me, MEF would be a better solution as you can bind the Import/Export on the interface.
i have a compiled dll library but i have no documentation about it. There is a way to get the public interface of a dll (at least function names, params numbers and type).
Thanks
You would have to decompile it and analyze each function, its calling convention, parametrs count, parameters meaning (unless it comes with some PDB, but I doubt it), I've done something like this before, it's complicated work, but it can be done.
In order to retrieve the public symbols (functions and variables) exported by a Dynamic-Link Library, one can use the well-known dependency walker. Parameters and Types are only available when the associated PDB file is available (which does not seems to be your case).
You could use the OLEViewer that comes with Visual Studio to view the TypeLib of the DLL if it is a COM library. This would give you the information you need.
Is it valid to develop a DLL in C++ that returns boost shared pointers and uses them as parameters?
So, is it ok to export functions like this?
1.) boost::shared_ptr<Connection> startConnection();
2.) void sendToConnection(boost::shared_ptr<Connection> conn, byte* data, int len);
In special: Does the reference count work across DLL boundaries or would the requirement be that exe and dll use the same runtime?
The intention is to overcome the problems with object ownership. So the object gets deleted when both dll and exe don't reference it any more.
According to Scott Meyers in Effective C++ (3rd Edition), shared_ptrs are safe across dll boundaries. The shared_ptr object keeps a pointer to the destructor from the dll that created it.
In his book in Item 18 he states, "An especially nice feature of
tr1::shared_ptr is that it automatically uses its per-pointer deleter
to eliminate another potential client error, the "cross-DLL problem."
This problem crops up when an object is created using new in one
dynamically linked library (DLL) but is deleted in a different DLL. On
many platforms, such cross-DLL new/delete pairs lead to runtime
errors. tr1::shared_ptr avoid the problem, because its default deleter
uses delete from the same DLL where the tr1::shared_ptr is created."
Tim Lesher has an interesting gotcha to watch for, though, that he mentions here. You need to make sure that the DLL that created the shared_ptr isn't unloaded before the shared_ptr finally goes out of scope. I would say that in most cases this isn't something you have to watch for, but if you're creating dlls that will be loosely coupled then I would recommend against using a shared_ptr.
Another potential downside is making sure both sides are created with compatible versions of the boost library. Boost's shared_ptr has been stable for a long while. At least since 1.34 it's been tr1 compatible.
In my opinion, if it's not in the standard and it's not an object/mechanism provided by your library, then it shouldn't be part of the interface to the library. You can create your own object to do the reference counting, and perhaps use boost underneath, but it shouldn't be explicitly exposed in the interface.
DLLs do not normally own resources - the resources are owned by the processes that use the DLL. You are probably better off returning a plain pointer, which you then store in a shared pointer on the calling side. But without more info it's hard to be 100% certain about this.
Something to lookout for if you expose raw pointers from a dll interface. It forces you to use the shared dll CRT, memory allocated in one CRT cannot be deallocated in a different CRT. If you use the shared dll CRT in all your modules ( dll's & exe's ) then you are fine, they all share the same heap, if you dont you will be crossing CRT's and the world will meltdown.
Aside from that issue, I agree with the accepted answer. The creation factory probably shouldn't define ownership & lifecycle management for the client code.
No it is not.
The layout of boost::shared_ptr<T> might not be the same on both sides of the DLL boundary. (Layout is influenced by compiler version, packing pragmas, and other compiler options, as well as the actual version of the Boost source code.)
Only "standard layout" (a new concept in C++11, related to the old "POD = plain old data" concept) types can safely be passed between separately-built modules.
I have a .NET DLL (that happens to be written in C++/CLI). Parts of it I want to expose via COM. I do this and register it using "regasm my.dll /codebase". So far so good. But then I change some things and the version number of the assembly changes plus I move the dll to a different folder. I register it again and look at my COM object in OLE/COM Viewer. I see something like this
InprocServer32 [Codebase] = file://c://foo/bar/my.dll
7.0.0.0 [Class] = My.Blah.Class
7.0.0.0 [Assembly] = Sync, Version=7.0.0.0, Culture=neutral, PublicKeyToken=1dd19234234
7.0.0.0 [RuntimeVersion] = v2.0.50727
7.0.0.0 [CodeBase] = file://c:/dooby/do/my.dll
7.0.0.27397 [Class] = My.Blah.Class
7.0.0.27397 [Assembly] = Sync, Version=7.0.0.27397, Culture=neutral, PublicKeyToken=1dd19234234
7.0.0.27397 [RuntimeVersion] = v2.0.50727
7.0.0.27397 [CodeBase] = file://c://foo/bar/my.dll
Questions about multiple versions:
So I think that the last COM object that was registered wins. It doesn't matter if I have my old 7.0.0.0 COM object registered, the 7.0.0.27397 is the one that will be created when I instantiate my COM object because I registered it last. Is that correct?
Oops I didn't keep around the 7.0.0.0 object. Is there any way to get rid of it? Is there any way to remove all versions of a COM object other than going into the registry and whacking it by hand?
Just out of curiosity, if I specifically wanted to instantiate a particular version of my COM object is there any way to do that? (I'm using C++ if you wanted to give a code example).
Is there any way I can just tell regasm to not store the version number because it just seems to be cluttering things up and I can't see what the benefit is. If my COM object went through significant API change I'd just change the GUID and progid, right? What if I don't want to register multiple versions (I don't).
I always set my COM visible assemblies up with a static AssemblyVersion for just this reason. If you want to have binaries tagged with a version, use AssemblyFileVersion instead.
Last registered object wins: yep
Not really. You can put stuff in your assembly's ComRegisterFunction/ComUnregisterFunction attributed methods to automate the cleanup, but if you leave old version droppings around, this is about the only way.
You'd do it with a different coclass GUID and/or ProgID (eg, MyCoClass.1, .2, etc). CoCreateInstance doesn't know anything about the version values- they're used by the CLR's activator to ensure it loaded the right assembly.
No- best thing to do is never change your assembly version (see above).
Components with the same CLSID should be compatible, especially if you've only changed the build number between assemblies. Here's the only relevant thing I found to confirm this by googling quickly.
To answer your questions directly:
Correct.
regasm /unregister
Look into Binding redirects.
Probably not.
I have a managed DLL (written in C++/CLI) that contains a class used by a C# executable. In the constructor of the class, I need to get access to the full path of the executable referencing the DLL. In the actual app I know I can use the Application object to do this, but how can I do it from a managed DLL?
Assembly.GetCallingAssembly()
or
Assembly.GetExecutingAssembly()
or
Assembly.GetEntryAssembly()
Depending on your need.
Then use Location or CodeBase property (I never remember which one).
#leppie: Thanks - that was the pointer I needed.
For future reference, in C++/CLI this is the actual syntax that works:
String^ appPathString = Assembly::GetEntryAssembly()->Location;
GetExecutingAssembly() provided the name of the DLL
GetCallingAssembly() returned something like System.Windows.Forms
GetEntryAssembly returned the full path, similar to GetModulePath() under Win32.