ILSpy assembly reference missing - .net-assembly

I have a project "A", which references 2 other projects "B" and "C".
For both references actual functions from these project are used in "A".
But when I open the assembly A.dll with ILSpy, it only shows "B" and not "C" under references.
If I remove the reference that is missing, my project no longer compiles, so it is in fact actually used.
What could be the reason for this?

The .dll will only contain an assembly reference if it uses types from the referenced assembly.
At compile-time it's possible that you need some additional assemblies.
Example:
C.dll:
class C { public void M1() {} }
B.dll:
class B : C { public void M2() {} }
A.dll:
class A {
public static void Main() {
new B().M2();
}
}
When building A.dll, the compiler will require both B.dll and C.dll so that it can list all methods in type B.
However the resulting IL code will only reference class B and method B.M2, so the compiler does not need to emit an assembly reference to C.dll.

Related

why constructor is not called for static objects created inside a class?

#include<iostream>
class A
{
public:
int x;
A()
{
x=4;
std::cout<<"inside A constructor"<<std::endl;
}
void function()
{
std::cout<<"inside function"<<x<<std::endl;
}
};
class B
{
public:
B()
{
std::cout<<"inside b constructor"<<std::endl;
obj.function();
}
private:
static A obj;
};
B b;
A B::obj;
int main()
{
}
In the above code obj.function(); is called for the first time it knows that obj is a member of class A,since initialization of static objects done during the compile time itself,but why not the constructor is called.
The constructor is called only after control hits the line A B::obj;
if i declare the static A obj; outside class B then the constructor is called.
why the behavior is different for both?
B b;
when the above line executes,the constructor of B is called first.
so "inside b constructor" is printed first.
Then when control reaches obj.function(); the obj is already initialized by the
compiler since it is a static type of object.
so obj.function() is called without any problem and "inside function" is printed.
Now the control reaches A B::obj; definition of static object.
so constructor of A is called and "inside A constructor" is printed.
note:
only when the definition of static object is called the constructor is used.
so only we donot see constructor of A when static A obj; is declared inside the class B.
Another question may arise why declaration is only made for static variables inside a class and definition needs to be called explicitly outside class?
The answer is the definition of class can be made inside a header file and this header file can be included in multiple *.cpp files.
so,If the definition is also present inside the class then the static variable will have multiple definitions which will cause erroe.
Inorder to avoid the above the definition for static members outside a class is made exclusively.

Expose types from embedded interop type to other assemblies

I have an ATL COM library that defines an enum and an interface in MIDL like:
[uuid(65785D49-574A-4B1B-95F1-B9C7F283364A)]
typedef enum Options
{
Option1,
Option2
} Options;
[
object,
uuid(2E3D1B1A-DF95-434F-836B-73FF1245B608),
oleautomation,
nonextensible,
pointer_default(unique)
]
interface IExample : IUnknown
{
HRESULT Test([in] Options option, [out, retval] BSTR* str);
};
I then create a managed assembly and reference the TLB, which creates a PIA and embeds the types (Embed Interop Types = true) into the managed assembly.
In the managed assembly, I now create a class that implements the interface:
public class Example : IExample
{
public string Test(Options option)
{
return option.ToString();
}
}
Now I would like to create a third assembly that references the managed assembly and creates the object and call into it, but it doesn't let me since Options is an unreferenced type (requires me to include the PIA generated from the typelib):
public class Equivalence
{
public void UseTest()
{
Example e = new Example();
e.Test(Options.Option1); // recognizes that it requires an ExampleLib.Options parameter, but that type isn't available
}
}
Using reflector, I can see it inside the managed assembly, but it isn't viewable by object browser:
namespace ExampleLib
{
[ComImport, CompilerGenerated, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2E3D1B1A-DF95-434F-836B-73FF1245B608"), TypeIdentifier]
public interface IExample
[Guid("65785D49-574A-4B1B-95F1-B9C7F283364A"), CompilerGenerated, TypeIdentifier("15a6cf97-c415-4866-bdfb-7da65edb1faa", "ExampleLib.Options")]
public enum Options
}
My managed assembly is itself a library intended to be distributed as an API, and I would like to expose this enumeration and interface so that it can be used by outside parties without having to deliver the PIA generated from the typelib of the ATL COM library. Is it possible?
Apparently this cannot be done. One of the errors (CS1748) pointed me to this post which says the PIA must be linked in by both assemblies.

Error while building the solution in vs2012?

I've created my project in vs2008.It works fine.But when i opened the solution and try to build it in vs2012 i am getting the following error in TransactionDB.dbml page.
a partial method may not have multiple defining declarations
What could be the problem??
.net supports partial methods.
It means you write a definition in one part of the partial class and the implementation in another. Like this:
partial class MyClass
{
partial void MyPartialMethod(string s);
}
// This part can be in a separate file.
partial class MyClass
{
// Comment out this method and the program will still compile.
partial void MyPartialMethod(string s)
{
Console.WriteLine("Something happened: {0}", s);
}
}
In your case I you have the two definitions of the partial method causing the compiler to fail.
Source MSDN
The defining declaration of a partial method is the part that specifies the method signature, but not the implementation (method body). A partial method must have exactly one defining declaration for each unique signature. Each overloaded version of a partial method must have its own defining declaration.
To correct this error
Remove all except one defining declaration for the partial method.
Example
// cs0756.cs
using System;
public partial class C
{
partial void Part();
partial void Part(); // CS0756
public static int Main()
{
return 1;
}
}

How to access a class in a namespace which is in different project?

I have three projects under another project of which each contains one namespace. Now among them I need to call a class which is under a namespace in visual studio 2008. Please don't ask me to add the dependencies to the main project so that I can access the namespace and all the classes in that just like local namespace which I can't do due to some restrictions. Tell me something like derived class concept so that I can access that class.
The LanguageTable class which I want to call is as follows:
#define GFX_LANGUAGE_MAX 20
namespace gfx_viewer_win32
{
public ref class LanguageTable
{
public:
static Dictionary<String ^, List<String ^>^> ^ language_string_table;
static array<String ^> ^language_string_id;
LanguageTable(void)
{
}
~LanguageTable(void)
{
}
};
}
The place from where i want to call LanguageTable class is as follows:
#pragma once
using namespace gfx_coder_prj_parser;
namespace Code_generator
{
public ref class CCodeGenerator : CCodeParserMultiLayer
{
CCodeGenerator(void)
{
}
~CCodeGenerator(void)
{
}
/*============I want to call LanguageTable class from here==========*/
};
}
If you don't want to add the assembly of LanguageTable class as a reference, you can reach it by System.Reflection. First load the assembly and create an instance of LanguageTable and now you can call methods,access properties of it by searching for by their names like
Assembly ^ langTableAssembly = Assembly::Load("assembly_name" or binary_data_of_assembly );
object ^ langTable = langTableAssembly->CreateInstance("gfx_viewer_win32::LanguageTable", ...with_other_params);
Type ^ langTableType = langTable->GetType();
MemberInfo ^ langStringID = langTableType.GetMember("language_string_id")[0];
MethodInfo ^ someMethod = langTableType.GetMethod("method_name");
someMethod->Invoke(langTable, ...other_params);
It is not a good approach though. It depends on the names, any change of the names (via refactoring etc.) you have to fix the code above. And I cannot say, this has the best performance.
Lastly, once loaded, the assembly of LanguageTable will not be unloaded during the execution of program. If you wish to unload it, this is another story called "playing with Appdomains".
Here and here are some links to begin with.

Create Managed Object From Unmanaged Class Function

I am trying to create a Managed C++/CLI object in unmanaged code.
Is this possible?
If so, am I doing it right? see code below
#include <vcclr.h>
#include <ManagedClass.h>
// compiled with /clr
namespace X
{
class UnmanagedClass
{
UnmanagedClass(){}
~UnmanagedClass(){}
gcroot<Y::ManagedClass^> m_guiControl;
void functionA()
{
m_guiControl = new gcroot<Y::ManagedClass^>;
}
}
}
// compiled into Managed dll with /clr
// in file ManagedClass.h in a separate project
using namespace System::ComponentModel;
// more usings here ..etc
namespace Y {
public ref class ManagedClass : public System::Windows::Forms::UserControl
{
// implementation here
}
}
When I compile the UnmanagedClass source file, I keep getting a whole lot of errors with the first one being error C2039: 'ComponentModel' : is not a member of 'System'. How come it is not recognising ComponentModel?
I thought this was suppose to be IJW (it just works) ;-)
Here's an example for a wrapper:
class UnmanagedClass
{
gcroot<ManagedClass^> m_managed;
public:
UnmanagedClass()
{
m_managed = gcnew ManagedClass();
}
};
Look here:
C++/CLI - Managed class to C# events
wrapper to c++/cli
Edit:
When you get an error on a using statement, and you know it's supposed to exist, It's usually because that dll isn't referenced.
Go to the projects references, choose add reference.
You can add .Net assemblies in the .Net tab. Find the one you need and add it.

Resources