What is a global method in .net? I'm talking about the ones created by the ModuleBuilder.DefineGlobalMethod method.
Can these methods be called from C# or other .net languages?
Hard to talk about this at all in familiar terms, this capability is not at all exposed in the C# or VB.NET languages. The C++/CLI compiler uses it however. The way it is shown in disassemblers like Ildasm.exe or Reflector is also not standardized.
Perhaps the best angle is Reflector, take a look-see at the System.Data.dll assembly. It is in an unnamed namespace ("-" in Reflector), <Module> node. The .cctor you see there is a module initializer. Same kind of animal as a static class constructor but at the module level. It runs when the assembly gets loaded. C++/CLI uses it to initialize the C runtime library.
The ___CxxCallUnwindDtor() method you find there is an example of a "global method". The C++/CLI language doesn't give any way to make these kind of functions public, they are always embedded in the metadata with internal accessibility. And can thus not be called directly from a C# or VB.NET program. I haven't played enough with ModuleBuilder to know if that can be messed with at all beyond what C++/CLI does. This is all very obscure and not actually that useful.
Global method means that the method can be called without fully qualifying it's name ie
Method(Param) instead of Module.Method(Param).
In vb a public method inside a module is global.
In c# a public static method in a static class is global.
Related
The issue is fairly simple, I have some constants in a C++ namespace that I would like to wrap using SWIG 2.0.8. It looks something like this:
namespace Example {
static const float PI = 3.14159f
...
/* Lots of classes are here */
}
Unfortunately SWIG handles this rather awkwardly. In the C# case, it adds the constants to a class with the same name as the namespace so it must be accessed by using Example.Example.PI even when I am explicitly using Example (due to masking by the module name).
In Java, its even worse as it does not treat it as a constant at all and I am forced to call it using Example.getPI() as a method call instead of a constant class variable.
If I move the constants to the global namespace, this seems to work but then the variables must be accessed using ExampleConstants.PI.
Ideally, I would like both languages to be able to access the constants via Example.PI to be consistent with C++. But a compromise that I would be happy with is if I could have a Constants class inside my namespace so that I can use Constants.PI in either language. But of course, C++ does not allow non-integral types to be defined inside a class and this is still not solving the issue in Java.
Is there any elegant way to handle these namespace constants with SWIG?
And if not, is there a way I can manually add a Java or C# class to define them?
I solved similar problem for C++ - C#. I am not sure if this is exactly what you are looking for, but I hope you will find some info useful for you.
I have not touched Java code in my project.
Swig solution.
I created class with public static parameterless functions in C++.
Then I exported them to C# using SWIG.
I specified namespace for C# in command line with -namespace <name> key. More details available at page SWIG and C#
As a result you can impelement solution to access your constant with Constants::PI() and Constants.PI()
Direct solution
If you would like not to use SWIG or other library, you should use PInvoke. There are a lot details and special cases when working with it. Most comprehensive article on subject I have found is Mono Interop with Native Libraries
You should consider JNI for Java.
Note, that C++ functions are exported without namespaces as pure C functions and you should create C# class and create functions with DllImport attribute to wrap functions back to namespaces.
In general if your C++ interface is more or less fixed and/or small I would adhere direct solution, because SWIG layer has many-many specific cases which should be learned along with PInvoke/JNI. But if you C++ interface frequently changed and requires a lot of effort to keep C++, C# and Java consistent, you defenitely need to consider SWIG.
You may find non-trivial example using PInvoke at https://stackoverflow.com/a/11909571/13441
Concerning C++ constants. You can specify C++ constant inside class, refer to C++ static constant string (class member) for details.
I use SWIG 1.3.40.
Hope this is helpful.
I have to communicate with a controller that uses an unmanaged DLL in C#. The documentation isn't very helpful for the DLL and I have no experience with talking to DLL's. The company does provide a sample VB project with a class that wraps the DLL from VB. The class is called ctccom32v2.
I thought that since the dirty work of calling the unmanaged DLL is already done including structs and other variables, I could use that class to create a VB class library. I figure it will save me a lot of time and effort. So I added that class source file to a VB class library project and it spat out a dll when built. I then added that dll to my C# project references and I am able to see the functions in the reference browser. The library I created is named CTC_Lib.
(if your wondering why I just don't write my program in VB and use their class, I prefer and I am more comfortable working in C#)
The problem I am running into is this:
If I create an instance of the library using
CTC_Lib.Ctccom32v2 ctc = new CTC_Lib.Ctccom32v2();
and then attempt to type ctc.somefunction, intellisense shows a few default methods like Equals, GetHashCode, etc. I do not see any of the Ctccom32v2 functions which expose the unmanaged DLL.
if I type the library and class name manually like so:
CTC_Lib.Ctccom32v2.
The intellisense list pops up with all of the functions in Ctccom32v2.
If I add another class to the VB class library (Lets call it "somelib") and stick a simple function into it:
Public Function add() as Void
Return 1+2;
End Function
I then use the same method for creating an instance:
CTC_Lib.somelib ctc = new CTC_Lib.somelib();
the function "add" now pops up in the intellisense window by simply typing ctc.
Could it because the way the functions are declared in the VB class? Here is one of MANY functions in the VB class, they are all declared the same using "Declare Auto Function":
Declare Auto Function CtOpenConnection Lib "Ctccom32v2.dll" _
(ByVal ConnectID As Integer, ByVal CommPort As Integer, ByVal Address As Integer) As Integer
I don't know what Auto function means but that does not expose the function when you attempt to create an instance of the class it resides in.
If this is or is not the proper way to call those functions within the VB class library please let me know, I am a novice. Also, forgive me if some of my terminology is incorrect; I am not good with programming jargon (yet).
The intellisense differs in your two scenarios because the unmanaged DLL lacks the required metadata to properly display the information about the functions. Your VB function does possess that metadata.
You already know the workaround; type the library and class name manually. Alternatively, you can wrap the unmanaged functions in managed VB methods, which will provide the needed metadata for intellisensing.
See the MSDN documentation on the Declare statement. This looks similar to declaring an extern method in C#. I think what you're missing is the access modifier. It should be like Public Declare ... to allow it to be used outside of where it's declared.
If that wasn't the issue, you might want to declare it as a Public Shared Function in a public class, using DllImport. An example of that is shown at the bottom of the Declare statement doc.
It can also be useful, maybe for this, and for C#/VB conversions in general, to decompile your assembly in ILSpy and see what is generated due to these lines.
Why we put main() method always inside the class in C# while in c++ it always placed outside of the class.
The C++ language designers followed the lead of C and so the main function is a plain function.
The C# language designers made the choice, when designing the language, that all methods must be part of classes.
For historical reasons. C++ evolved from C, which had a global main() function. C# is much younger and was designed from scratch. One of the design features of C# is the absence of global functions, so the main function has to belong to a class.
Because in .NET you can place methods only inside types. You cannot have them floating around in the empty space. C++ has its legacy from C which is not an OOP language so you could define functions anywhere.
You cannot place method outside class/struct in C#. Each method must be in class/struct
It is a convention. Which is in line with Java (also follows the semantic of having a method inside class).
C# is complete object oriented language where everything is considered as objects. Hence, Main() is kept inside class.
I'm attempting to consume a dll written in C++ from a C# application. I have 3rd party source code for the C++ dll (the Cyclone physics engine) and do not want to manually port it over to C#.
In the C++ project
I changed it to output a dll. I changed it to use the /clr flag. I changed it to use Multi-threaded Debug DLL (/MDd) because that was the only one compatible with /clr and also compiled.
In the C# project
I added a reference to the dll. I'm using the cyclone namespace.
At first there was absolutely nothing under the namespace. I think this is because in the C++ code, all classes were declared with no access modifiers and the default is private. So for the class "Particle" I changed the definition to:
public class Particle
{
//...
}
Now I can successfully declare a variable of type Particle from the C# code. However, intellesense and the object browser report Particle to be a struct (?) and it doesn't contain any methods at all. The c++ code declares a bunch of methods after "public:" access modifiers so I don't know what the problem is.
For example,
public:
void integrate(real duration);
What am I doing wrong?
The Particle class is not a managed class, hence it is treated as a struct. You need to use the ref keyword to make it managed and garbage collected. You also need to do the same to every other class that references it which might be a problem. The best solution I think, is to create a managed wrapper class that uses the Particle class internally. This wrapper class can then be referenced by .net.
See here:
I have not actually run into your exact problem before, but I have used C++ dlls in c# before. Typically when calling a dll like that you would use the dllImport keyword. Basically you can define a class that imports all the types and methods from the c++ dll. You can then call those wrapper classes.
I am far from an expert on it, but I have used it to get access to win32 methods and some other libraries that I needed to use.
This link on codeplex has a few links tools that might help. But the most important is probably the Interop Assistant. It can generate the C# wrappers for your c++ dll.
This isn't exactly what you are asking, but I thought it might help to look at a different direction.
Try declaring the c++ class with the ref keyword:
public ref class Particle
Do you have a reference to COM Interop?
Can someone explain the difference between a class and a module. When do you use one versus the other? I am using C#.
Update: I do mean the C# equivalent of the VB Module.
This depends heavily on which "Module" you are referring to.
Visual Basic's Module
There is no real equivalent in C# for a VB.Net Module. In ways it's similar to a static class in that you cannot create an instance of it and all of the members inside of it are static. In C# this requires an explicit static keyword while in VB.Net it's implicit.
The big difference though is in name lookup. In VB.Net if a Module is in scope then any of it's methods can be called without qualification. This is not true for C# static classes.
Besides name lookup, the primary difference between a class and a module is that a class is typically useful only with an instance of the type.
System.Reflection.Module
A module in this context is a portable executable file (dll or exe). A given DLL/EXE can be composed of several modules if it's a multi-file assembly. It has no real relationship to an individual class.
(Maybe I should be clear, there are no "Modules" in C# as in VB.NET's "Module")
There are no modules in C# (like the modules in VB or VB.NET). So, instead a module is one which is compiled and packaged into an assembly, it's more logical.
Whereas class is a well defined entity. A module may use a class (or classes), to function. (Again the word "module" is used logically)
The word "Module" is also used in a context quite different, in System.Reflection.Module
A module is a compiled dll or exe, it contains the compiled classes. A class is the same as a class in most any other language.
Also, modules, whether it's one or more are what make up Assemblies in .Net
Remember that once it's compiled in .Net it doesn't matter what language it was written in, it's all IL, so the terms you're describing are pretty much language agnostic at that point.
A class is an independent unit of data and functions - fields, properties, and methods.
A module refers to the code generated from a single physical file. Most of the time, when you write code in Visual Studio, a single file will contain a single class, interface, or struct.
Compiled DLLs or EXEs are called assemblies. An assembly can contain any number of modules as well as other resources such as version information. By default, when you compile an assembly in Visual Studio, the assembly contains every module defined in the project.
As for when you would use them: You use classes, interfaces and structs all the time, those are the basics. Modules are things that you generally don't have much control over; again, it's a generally accepted practice to have one type per file which compiles to one type per module.
You would normally use a separate assembly when you want to reuse certain types (contained within certain modules) across multiple projects. You might also use it to create a hard boundary between different components of an application, i.e. put your database logic in one assembly and your business logic in another.
There's no equivalent in C# to the VB6 module. The closest would be a static class, but even then, the members of the class are not global, as they would be in a VB6 module.
From Microsoft docs,
A module is a portable executable file, such as type.dll or application.exe, consisting of one or more classes and interfaces. There may be multiple namespaces contained in a single module, and a namespace may span multiple modules.
One or more modules deployed as a unit compose an assembly. For information about creating an assembly with more than one module, see Multifile Assemblies.
Note that a .NET Framework module is not the same as a module in Visual Basic, which is used by a programmers to organize functions and subroutines in an application.
.NET Framework module is not the same as a module in Visual Basic, which is used by a programmers to organize functions and subroutines in an application ( see module class in C#)
If you are used to the VB6 module (method that is accessible wihout an instance), declare the functions as static in c#