I Wanted to convert a c# code to j# and somehow managed to get over dllimport and marshalas.
Problem is, when a function has a reference to an object - ref isn't recognized
public static native int Mathod(ref Type type, int flags);
Anyone has any experience with j# and know how to send references to a method (or define a type in a method as a reference)
I'm pretty sure that you can't do this directly.
Everything is passed by value in real Java, and presumably in J# too.
In recent versions of Java you can workaround the restriction by using AtomicReference, but I very much doubt that J# is up-to-date enough to support this.
You could try changing the method signature to accept a single-element Type[] array, and then mutate that array element. This would allow you to achieve a similar outcome to ref. The downside is that you'd need to change the call-site and the method itself to wrap and unwrap the variable in the array. (Although you could create your own custom type to encapsulate the wrapping and unwrapping if it simplifies things.)
Related
I need to pin a static value-type field in memory, and I need the pin to be long-term, i.e. using a pinned GCHandle (or equivalent), not a pinned local variable (e.g. fixed blocks in C# or pin_ptr in C++/CLI)
I'm going crazy figuring this out, and I can't accept it isn't possible
So, I can pin a value type static field locally to a function, using fixed/pin_ptr, but I lose the pin when the function returns
With a GCHandle of type GCHandleType.Pinned, I can pin objects for as long as I like, but it only works on objects, reference types. I know value type static fields are internally stored as boxes (e: seems this only applies to non-primitive types, and I'm dealing with primitives), but I can't get a reference to the internal box object: if I pass the field to GCHandle, I create a new box from the current value of the field
From reading on .NET internals, I know that statics are stored inside assembly objects, which used to be non-GC and guaranteed to stay fixed in memory. But assemblies have been made collectible in recent versions of Core and Framework, and I don't know if this still applies (probably not, or we wouldn't need FixedAddressValueTypeAttribute)
I can't mark the field as [FixedAddressValueType], because it's in a third-party assembly that I can't replace or modify
So, to sum up: I can pin anything, as long as I do it locally to a function. I can pin non-locally, but only if I have a reference to an object. Value type static fields are wrapped in an object, but I can't get a reference to it. Is there any hope of achieving this, ideally not relying on implementation-specific internals, or it's simply unsupported?
(... and to make it even harder, ideally, I need to do it from unmanaged code, using the native COM APIs. And, again ideally, I need to support both .NET Framework and .NET Core)
I have a library whose functionality I want to eventually expose to .NET. The method I want to expose has the following signature:
void DoSomething(std::list<SomeStruct>& someList);
The variable someList gets populated by DoSomething.
I know how to export from the library already. My main question is what would a ".NET friendly" interface look like for this function? I'd assume that std::list is a bad idea if I want to use C# with P/Invokes.
What other options are there? As the caller, I won't know the size of the buffer that I should pass in ahead of time. Also, as the caller, I'd rather not make multiple calls to the function with small fixed-sized buffers nor would I want to pass in a super large buffer.
What's the best practice for this case?
You can define a struct for use in the pinvoke call. Decorate it on native and mnaged sides, so that the packing is the same on each side. As for the variable sized out parameter, you could use ::GlobalAlloc to allocate an array that can then be deallocated in C#. Pass out an item count as well. In C#, the Marshal type has various methods to use to work with a GlobalAlloc'd array.
Let's assume I have an unmanaged class Test:
class Test
{
public:
int SomeMethod(int a, bool b);
};
To create a new instance of Test, I'd:
Test *test = new Test();
My goal is to embed Mono so that managed code could call unmanaged methods (like Test::SomeMethod) in a specific object. I represent that object by passing a pointer of that object to the managed method, like that:
void *args[1];
args[0] = &test;
mono_runtime_invoke(init, NULL, args, NULL);
Here is how the managed method that is being invoked looks like:
public static void Init(IntPtr test)
{
}
From here, how can I call Test.SomeMethod?
I thought about using emitting the CALLI instruction, using System.Reflection.Emit, but how can I refer to the object that the pointer test (the first parameter of Init) is referring to?
I do not want to use DllImport.
You might be interested in CXXI. It creates a managed assembly based on your C++ headers and allows you to work with C++ objects as if they were normal managed objects.
As far as I understand it, it's not finished yet and works only with C++ code compiled by GCC.
Can't be done (Or at least shouldn't be done).
You're trying to directly mix two completely different execution environments - the reason why DLLImport exists is to allow the compiler to solve this problem.
In .NET, you can create mixed-mode applications (C++/CLI) which allow managed code and unmanaged code to co-exist in the same binary (and call each other), but since you're talking about mono, I'm assuming that option is out.
Managed environments like .NET have strict type rules, garbage collection and other features that simply don't work with unmanaged code and data.
You can use an internal call, if you don't want to use DllImport.
See https://github.com/mono/mono/blob/master/samples/embed/teste.c the mono_add_internal_call() invocation and the C# code in the test.cs file.
This works mostly like DllImport, except there is no marshalling done for you (a string object in C# code will appear as a MonoString* in the C code, not as a char*, for example).
In any case, note that both the function you could access with DllImport and the function pointer registered with mono_add_internal_call() must be C functions, not C++ member methods.
I'm working with a GIS based math library that wraps lower C/C++ code in C#. Many of the parameters are pass by reference for the sake of receiving multiple outputs. If I only want some of the outputs, how can I ignore the other parameters? Is the best solution to create a dummy variable and pass it by reference and ignore its output?
Is the best solution to create a dummy variable and pass it by reference and ignore its output?
Yes, that's what I do.
I usually just create an object in my code like
object NotNeeded = null;
or something similar that says that its effectively an unnecessary parameter and then use that repeatedly. I'm not sure whether or not that'll work, though, because I'm not sure what the GIS library is doing on the other side. If it needs an actual non-null value for each one, that might be problemeatic.
You have a few choices:
dummies
wrapper methods
change the Interop Imports. Your ref parameters are most likely pointers in C++, and if they allow null then you could change the import to use pointers (IntPtr) and pass null / IntPtr.Zero.
But a few dummies is probably the best (easiest to read) option unless you have really many, many calls.
The "best" is the "only" compile-time method that I am aware of: foo(bar, ref dummy) -- but feel free to wrap away these dummy variables if it makes sense.
If there are instance methods, creating appropriate Extension Methods wrappers can help hide the "useless" dummy variables in a relatively seamless fashion.
Happy coding.
Before I ask my question, please take a look at this example function:
DateTime.TryParse("01/01/2000", out oDate)
Why do I need to specify the out keyword? Shouldn't the compiler know this from the function's definition?
I'm asking this out of pure curiosity in the hope that I will learn something new about the compiler.
I should also clarify that I'm asking about the C# .NET 3.5 compiler in particular.
The out keyword could be implied by the compiler but my understanding is that the C# team decided to make the out keyword explicitly required by the caller of the function to increase visibility as to the nature of the parameter.
The compiler does know, you may not. It's a way of letting you know that the parameter you are passing can change in this function you are passing it to.
It's not about what the compiler knows, it's all about making sure the developer realizes this call can and will change the value of variable X.
A lot of this has it's roots in C++ where a reference value needs no call site monitor. It's impossible to look at a C++ call and know exactly what it will do. Parameters passed by reference and value in C++ have huge differences in semantics.
Yeah the compiler could figure it out, but this way you know that it is going to modify the variable you are passing in.
the C# language has a lot of what I would call safety nets that explicitely tell the programmer what is going on. A couple of examples are:
No fall through in switch statements.
You can't assign a value in an if statement: if(x = 5) throws an error instead of evaluating to true.
http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.80).aspx
"The out keyword causes arguments to be passed by reference. This is similar to the ref keyword, except that ref requires that the variable be initialized before being passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword."
Since the DateTime.TryParse does not require oDate to be initialized, you must pass the out keyword.
OK, I'm not a C# expert, so if I mess up will somebody please correct me?
There's two ways to pass a parameter to a C# function: by value and by reference. The big difference here is whether modifying the parameter inside the function modifies the variable used to call it. This is not something I'd trust the compiler to decide for itself.
Since you want oDate to be a variable passed in from the caller, and changed, you want it passed by reference.
The other question is whether it should be initialized or not. C# likes to catch when variables are used while uninitialized, since that's almost always an error. In this case, you might well just declare what you're passing in, and use TryParse() to give it its first value. This is a perfectly legitimate technique, so the compiler should allow it. This is another thing I wouldn't trust the compiler to get right. (I assume the compiler also checks to make sure an out parameter is initialized before use in TryParse().)
So, "out" serves two purposes. It establishes that the parameter is passed in by reference, and that it is expected to be initialized inside the function. Neither of these can be determined by the compiler.