Thread: Assembly Problems

  1. #1
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853

    Assembly Problems

    I do this in order to dynamically generate code:
    Code:
    CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
    CompilerParameters cp = new CompilerParameters();
    cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");
    cp.ReferencedAssemblies.Add("System.dll"); 
     cp.ReferencedAssemblies.Add(@"C:\Users\Gift\Desktop\MJsniffer\MJSniffer\Commands\bin\Debug\Commands.dll");
    cp.GenerateInMemory = true;
    cp.OutputAssembly = "myasm.dll";
    CompilerResults result = provider.CompileAssemblyFromSource(cp, lcCode);
    Assembly loAssembly = result.CompiledAssembly;
    object loObject = loAssembly.CreateInstance("ScriptSpace.ScriptClass");
    The problem is that this new assembly doesn't work with the assembly I add on the read line. The problems are that it doesn't find the methods inside it. I have a class like
    Code:
    namespace A
    {
    static class B 
     {
      static void c() {}
     }
    }
    Which is in the Commands.dll. I cannot use the B.c() method. I created two assemblies to reproduce this and I see that I can still not use a static method from one assembly to the other.
    I can also not instantiate any class inside the assembly or use any variable.

    Am I doing something wrong here? How can you make one assembly correctly use another one?
    Last edited by C_ntua; 06-19-2010 at 09:58 AM.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    What are you trying to do? If you are trying to dynamically link with a DLL or assembly there is a much easier way to do it.

  3. #3
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Sounds like you've got the C# version of this. See here Accessibility Levels (C# Reference)

    Top-level types, which are not nested in other types, can only have internal or public accessibility. The default accessibility for these types is internal.
    Internal means 'used in this assembly only', trying to use them from a different assembly isn't going to happen unless you decorate them as public.

  4. #4
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    You enter code on a textBox and it is executed without the need to close/open the program again.

    The above should create an assembly and an instance of it and is able to execute its methods. The assembly generated uses a DLL I create. My goal is not to have to compile a whole piece of code with this method. Just to generate a small piece of code, essentially a single function, that will have access to data from the current program executed. So
    a) I have a program that generates code and executes one function of it
    b) I want that generated code to have access to methods and data from this program. That is why I thought to put the methods in a DLL and make the generated code use that DLL. It links correctly, but it throws an exception when a method from that DLL is run or an object is instantiated...

  5. #5
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by adeyblue View Post
    Sounds like you've got the C# version of this. See here Accessibility Levels (C# Reference)


    Internal means 'used in this assembly only', trying to use them from a different assembly isn't going to happen unless you decorate them as public.
    They are public, forgot to put that on my example.

  6. #6
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Solved. I had to add the reference of that DLL to my main project as well. Which I don't fully understand why

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Keep in mind if you add the reference this is a static link. You can define an interface that your object in the DLL adheres to and then dynamically link using the visibility the interface provides. You do not have to add the DLL as a reference in your project. If you do this it means that when the DLL or the code using the DLL changes, both projects must be re-compiled. With true dynamic linking this is not the case. However if you must include a reference there is a way to get around the recompile if the interface changes. If you add functions to the end of the interface for either object new code can use the new functionality and older code can use the existing functionality and you do not have to recompile. The catch is you must add to the end of the interfaces. If you move existing code around in the interface or alter the order then you must recompile all projects who use the interface. This works in C++ and I'm fairly sure it works in C# as well. It is more related to how Win32 looks at DLLs when loading them than it does the language being used.

    Mono does dynamic linking for you (in a convoluted way) and you could certainly use mono for this task so I guess I'm a bit confused.
    Last edited by VirtualAce; 06-19-2010 at 03:03 PM.

  8. #8
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Oh, that explains some strange errors I was getting, though I just figured re-compiling always helps.

    The dynamic linking is done using System.Reflection.Assembly.LoadFile()? Or DllImport? Or any of the two?

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yes, dynamic is done via the LoadFile(). DLLImport is the P/Invoke way of doing it which is both messy and forces you to build a class in C# that interfaces with a C impl or DLL which can then interface with a C++ DLL. C++/CLI takes all this pain away. You can even write a C++/CLI DLL that interfaces with the Win32 API under the hood but if I want to bring in a Win32 API call to C# I normally use the ugly P/Invoke DLLImport stuff. After all you usually only bring in a few isolated functions from the API.


    Dynamic load
    Code:
    public interface ISomeInterface
    {
        void Foo();
    };
    
    Assembly asm = Assembly.LoadFile(fileName);
    if (asm != null)
    {
       Type classType = asm.GetType(typeName);
       if (classType)
       {
            ISomeInterface resultInterface = Activator.CreateInstance(classType) as ISomeInterface;
       }
    }
    
    if (resultInterface != null)
    {
         resultInterface.Foo();
    }
    This is assuming that the typeName specified is a class that derives from ISomeInterface. After the activation you should then be able to call any public function in the interface.

    EDIT:
    After messing around with this a bit more I've found that using Assembly.LoadFrom() is probably a better option. LoadFile() forces you to use absolute paths (I'm not sure of the logic behind this) so I've altered my tests to use LoadFrom(). All I had to do was set my working directory and then pass in the filename (with extension) and call LoadFrom() and it loaded the DLL. Again I have no clue why LoadFile() is so restrictive. If you pass a filename to LoadFile() it will crash b/c it actually is attempting to parse the string and is looking for a drive letter and slashes. Very weird indeed.
    Last edited by VirtualAce; 06-20-2010 at 06:56 PM.

  10. #10
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Thank a lot. I guess that solves my problem.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Most Common problems in C
    By Bayint Naung in forum C Programming
    Replies: 18
    Last Post: 06-02-2010, 08:20 PM
  2. Assembly Help PLease!
    By Tleggo in forum C Programming
    Replies: 2
    Last Post: 05-24-2002, 03:29 PM
  3. bubble sort in assembly language!!!!!!
    By lorenzohhh in forum C++ Programming
    Replies: 1
    Last Post: 04-15-2002, 08:30 PM
  4. Assembly forum
    By Garfield in forum A Brief History of Cprogramming.com
    Replies: 11
    Last Post: 11-18-2001, 08:03 PM
  5. DJGPP assembly syntax ills...
    By VirtualAce in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 11-11-2001, 02:54 AM