I found a code online which i'm using in my Program, but to my surprise i found out there was a variable/function declared twice...
Now, If i'm to send any value to the DLL, which of the two would i send info to?
One use out, while the second does not...
See Code:
[DllImport("msman.dll", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Ansi, ExactSpelling=false)]
public static extern bool receive(int ID, double[] Bid, double[] Ask);
public bool receive(int ID, out double first, out double second)
{
bool flag;
double[] Array1st = new double[1];
double[] Array2nd = new double[1];
if (Form1.receive(ID, Array1st, Array2nd))
{
first = Array2nd[0];
second = Array1st[0];
flag = true;
}
else
{
second = 0;
first = 0;
flag = false;
}
return flag;
}
And, why is it possible to declare two variables..
My C# isn't great, but this looks like a standard case of method overloading.
Note the signature for each method
A: public static extern bool receive(int ID, double[] Bid, double[] Ask);
B: public bool receive(int ID, out double first, out double second)
A takes the following parameters: int, double[], double[]
while B takes int, double, double. Note the difference in types. So when you call it, the compiler says "oh, you want to call receive with an int and two double arrays. Got it, here you go!" and serves up A
Example of how the call works:
int x = 1; double y = 1.0; double z = 2.0;
receive(x, y, z); // <-- this calls the second method (B).
int x = 1; double[] y = new double[1]; double[]z = new double[1];
y[0] = 1.0;
z[0] = 1.0;
receive(x, y, z); // <-- this calls the first method (A)
Methods can be overloaded, that is, they can have the same name as long as the parameters differ (overloading on return type only is not allowed).
Hence this is valid:
void Foo(int x) { }
void Foo(char x) { }
Or, in your case:
bool receive(int ID, double[] Bid, double[] Ask);
bool receive(int ID, out double first, out double second)
Note that this is a standard language feature in many other languages, including C++.
Method overloading is object oriented concept where method can have same name and only parameters(signiture of method) are different.
using System;
class Test
{
static void receive(int x, double y)
{
Console.WriteLine("receive(int x, double y)");
}
static void receive(double x, int y)
{
Console.WriteLine("receive(double x, int y)");
}
static void Main()
{
receive(5, 10.2);
}
}
See here https://msdn.microsoft.com/en-us/library/aa691131(v=vs.71).aspx
Related
I've been benchmarking some C# struct creation, and I've been surprised to find that creation of a nested struct is significantly slower than the un-nested version. I would have expected the JITter to basically produce the same assembly for a flat and nested structure, but this appears to not be the case.
Does anyone have an explanation for why the struct construction in my test code below doesn't get optimized down to just writing the 3 doubles? It seems to (if I'm reading the assembly correctly) zero and create a temporary memory location before writing the values to the final location - presumably actually creating a temporary copy of the nested struct.
And in the follow-up, is there a way to avoid this extra work such that the nested struct has similar creation speed to the un-nested one?
public class StructBenchmarks
{
public struct Vector3_dp
{
public Vector3_dp(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
public double X;
public double Y;
public double Z;
}
public readonly struct ContainsVector
{
public ContainsVector(double x, double y, double z)
{
m_vector = new Vector3_dp(x, y, z);
}
public ContainsVector(Vector3_dp input)
{
m_vector = input;
}
private readonly Vector3_dp m_vector;
}
private ContainsVector m_vector1;
private ContainsVector m_vector2;
private Vector3_dp m_vector3_dp1;
private Vector3_dp m_vector3_dp2;
// 0.2ns
public void Vector3_dp_Construction()
{
m_vector3_dp1 = new Vector3_dp(20, 30, 40);
}
// 3.8ns
public void Vector_Construction()
{
m_vector1 = new ContainsVector(20, 30, 40);
}
// 3.8ns
public void Vector_ConstructionFromVector3_dp()
{
m_vector1 = new ContainsVector(m_vector3_dp1);
}
// ~0ns
public void Vector3_dp_Copy()
{
m_vector3_dp1 = m_vector3_dp2;
}
// ~0ns
public void Vector_Copy()
{
m_vector1 = m_vector2;
}
}
And SharpLab link: https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8BYAKAAJLyABAZhoCZyBlDKAVzAwCEYA7MAAt82KAGtcZKuQDeU6VTrlcbThnIA1GF2i0A+gBMADvIWzTZxfS06o+4wAoDEdsAA2McgjTlnrj+QAnj5+7p4AXgCUFpbmFLGWABrkALxeANwxCZQAmqlBmfHZ0gBa+eGFxeQAvmRZZkqhAYmVxY0uYeQ5rdnt/p4lPQq1pPU09LDYznxugcqqXOQAwhB8GNgAlny4NhjQY3JFCUora5vbu9BOHQHevjeewff95FFj0odV0vh6AG7aeyg+T4MAA7poAbpDEYHHcnlEhrERu8rMtVustjtIVAHJc7NDyFsjOwMNEjrFPl9KD9/rZ8kSSYjLMjyZYjFANr9sBhPJNprMIbZ7EZyDTsUzKCzYuzOdzPKcMRdsaK/tiAIwS8gyrk8tFnTF4lW0wEMQpjbVywWA4VG7HCjXmjk6zx4m1ioXQ011VmUAD0vvIAAYAHQMbZjJTUFBWqHGPSnFQcLgbVYOMkUlHU1Ue4xq4FgmP4xwMQM+Wil8goQORTVSyz+8i0YMADnDPvGNGjePjq0TahTfDTB0zttsebSIPBCvOWNsDhLZYrVZrYzrZgbTdbknbka72J72wWGAHADEoBB8K7oUP25Tsu7AePyJO9YrZ4CHA/Y0Y1Sv22uFF3QthR7IxAhvDN22+bNrWhJ8vyLIwvX/MYI3oKNC1A8D00sO8EgQ+CYOgZCkQsEYgA=
I have this code:
public void myMethod()
{
int a = 10;
int b = 20;
Func<int, int, int> multiplyDelegate;
multiplyDelegate = Multiply;
multiplyDelegate += Multiply2;
Console.WriteLine(multiplyDelegate(a,b));
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Multiply2(int x, int y)
{
return x * y + 10;
}
By running myMethod, I expect the console to show the returns from both methods "Multiply" and "Multiply2" but only the return from the method "Multiply2" is shown. Have I done something wrong here or have I misunderstood the concept of delegates? From what I've learned a delegate is an array of references to methods.
From Using Delegates (C# Programming Guide):
If the delegate has a return value and/or out parameters, it returns
the return value and parameters of the last method invoked.
You are right delegate can store methods and invoke multiple methods at once. It will return the last one except if you explicitly Invoke them.
Using your code, here is an example of explicite Invoke for all of your collection of methods.
var results = multiplyDelegate.GetInvocationList().Select(x => (int)x.DynamicInvoke(10, 20));
foreach (var result in results)
Console.WriteLine(result);
EDIT :
This will work for function Func and not Action. Here is an example supposing it's an Action
foreach (Delegate action in multiplyDelegate.GetInvocationList())
{
action.DynamicInvoke(10, 20);
// Do Something
}
This second example work for Func as well.
I don't have any official sources for this, but I think what is happening is that you can't return two values from one delegate call. Therefore, the last value returned is used.
Although only the last return value is used, the two methods are indeed executed. We can prove this by printing some stuff before we return:
public int Multiply(int x, int y)
{
Console.WriteLine("Hello1");
return x * y;
}
public int Multiply2(int x, int y)
{
Console.WriteLine("Hello2");
return x * y + 10;
}
Both Hello1 and Hello2 are printed.
Only one object can be returned and since Multiple2 is the last to execute it get's outputted in the console.
There isnt a way to change that.
You could do:
public void myMethod()
{
int a = 10;
int b = 20;
Action<int, int> multiplyDelegate;
multiplyDelegate = Multiply;
multiplyDelegate += Multiply2;
multiplyDelegate(10, 20);
Console.Read();
}
public void Multiply(int x, int y)
{
Console.WriteLine(x * 2);
}
public void Multiply2(int x, int y)
{
Console.WriteLine(x * y + 10);
}
I had this question too and test several things like another way of setting method to the delegate but finally only usable way is to write another line after each set:
public void myMethod()
{
int a = 10;
int b = 20;
Func<int, int, int> multiplyDelegate;
multiplyDelegate = Multiply;
Console.WriteLine(multiplyDelegate(a,b));
multiplyDelegate += Multiply2;
Console.WriteLine(multiplyDelegate(a,b));
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Multiply2(int x, int y)
{
return x * y + 10;
}
I need to overload a method for it to be able to calculate the area of a circle, square, rectangle, triangle and a trapezoid. I think I've got them all figured out but the circle seems to be a problem.
static void Pole(int x, double y = 3.14)
{
Console.WriteLine(x * x * y);
}
static int Pole(int x)
{
return x * x;
}
static int Pole(int x, int y)
{
return x * y;
}
static int Pole(int x, int y, int z = 2)
{
return x * y / z;
}
static int Pole(int x, int y, int v, int z = 2)
{
return (x + y) / z * v;
}
static void Main(string[] args)
{
int x = 2;
int y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
I don't know what problem you're getting, but I can probably guess it's one of the following:
1) You're getting an error because one of your overload methods is returning void while the others are returning int (they all have to be the same)
or
2) What your Main method is calling is this method static int Pole(int x, int y) and not static void Pole(int x, double y = 3.14), which I'm assuming is the "Circle"; because you're passing in two ints instead of one int and one double.
Have you tried changing int to double for y in your Main method?
static void Main(string[] args)
{
int x = 2;
double y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
}
also why dont you just pass in one parameter and have it multiply by 3.14 for the Pole overload method that's tasked with calculating the circle?
/// <summary>
/// Method to calculate a circle
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
static double Pole(int x)
{
return 3.14(x * x);
}
static void Main(string[] args)
{
int x = 2;
Console.WriteLine(Pole(x));
Console.ReadKey();
}
Another tip: add some notes in your code. You have 5 methods named Pole, one accepting one more int parameter than the last one and each of the 5 methods are calculating for a different shape.
Adding a summary to each method or just a simple comment will help you and anyone else trying to read your code, moving forward.
Important: Because these are overloads, you're going to need to change all your methods to return double instead of int just for the sake of the "Circle" Pole method. Having it as the only void method was probably causing the error for you to begin with.
This should be enough to get you started:
//Circle
static double Pole(int x, double y)
{
if(y != 3.14)
y = 3.14;
return y(x * x);
}
//Square
static double Pole(int x)
{
return x * x;
}
//Rectangle
static double Pole(int x, int y)
{
return x * y;
}
//Triangle
static double Pole(int x, int y, int z)
{
if(z != 2)
z = 2;
return x * y / z;
}
//Trapezoid
static double Pole(int x, int y, int v, int z)
{
if(z != 2)
z = 2;
return (x + y) / z * v;
}
static void Main(string[] args)
{
int x = 2;
double y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
}
I have this code:
public void myMethod()
{
int a = 10;
int b = 20;
Func<int, int, int> multiplyDelegate;
multiplyDelegate = Multiply;
multiplyDelegate += Multiply2;
Console.WriteLine(multiplyDelegate(a,b));
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Multiply2(int x, int y)
{
return x * y + 10;
}
By running myMethod, I expect the console to show the returns from both methods "Multiply" and "Multiply2" but only the return from the method "Multiply2" is shown. Have I done something wrong here or have I misunderstood the concept of delegates? From what I've learned a delegate is an array of references to methods.
From Using Delegates (C# Programming Guide):
If the delegate has a return value and/or out parameters, it returns
the return value and parameters of the last method invoked.
You are right delegate can store methods and invoke multiple methods at once. It will return the last one except if you explicitly Invoke them.
Using your code, here is an example of explicite Invoke for all of your collection of methods.
var results = multiplyDelegate.GetInvocationList().Select(x => (int)x.DynamicInvoke(10, 20));
foreach (var result in results)
Console.WriteLine(result);
EDIT :
This will work for function Func and not Action. Here is an example supposing it's an Action
foreach (Delegate action in multiplyDelegate.GetInvocationList())
{
action.DynamicInvoke(10, 20);
// Do Something
}
This second example work for Func as well.
I don't have any official sources for this, but I think what is happening is that you can't return two values from one delegate call. Therefore, the last value returned is used.
Although only the last return value is used, the two methods are indeed executed. We can prove this by printing some stuff before we return:
public int Multiply(int x, int y)
{
Console.WriteLine("Hello1");
return x * y;
}
public int Multiply2(int x, int y)
{
Console.WriteLine("Hello2");
return x * y + 10;
}
Both Hello1 and Hello2 are printed.
Only one object can be returned and since Multiple2 is the last to execute it get's outputted in the console.
There isnt a way to change that.
You could do:
public void myMethod()
{
int a = 10;
int b = 20;
Action<int, int> multiplyDelegate;
multiplyDelegate = Multiply;
multiplyDelegate += Multiply2;
multiplyDelegate(10, 20);
Console.Read();
}
public void Multiply(int x, int y)
{
Console.WriteLine(x * 2);
}
public void Multiply2(int x, int y)
{
Console.WriteLine(x * y + 10);
}
I had this question too and test several things like another way of setting method to the delegate but finally only usable way is to write another line after each set:
public void myMethod()
{
int a = 10;
int b = 20;
Func<int, int, int> multiplyDelegate;
multiplyDelegate = Multiply;
Console.WriteLine(multiplyDelegate(a,b));
multiplyDelegate += Multiply2;
Console.WriteLine(multiplyDelegate(a,b));
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Multiply2(int x, int y)
{
return x * y + 10;
}
I have to call a C++ dll in C#. And the header of the dll is as following(simplified):
//Header of C++
struct vector
{
float x;
float y;
vector()
{}
vector(float x0, float y0)
{
x = x0;
y = y0;
}
};
struct unmanaged_struct
{
int int_var;
float float_var;
char* chars_var;
vector vector_var;
unmanaged_struct(int i, float f, char* ch, float vec_x, float vec_y)
{
int_var = i;
float_var = f;
chars_var = ch;
vector_var = vector(vec_x, vec_y);
}
};
// this function is used to output all the variable values of the struct instance
extern "C" __declspec( dllexport ) void unmanagedstruct_summary(unmanaged_struct* us_list, int length);
And I defined following class in C#
//CSharp
[StructLayout(LayoutKind.Sequential)]
public class Vector
{
public float x;
public float y;
public Vector(float f1, float f2)
{
x = f1;
y = f2;
}
}
[StructLayout(LayoutKind.Sequential)]
public class UnmanagedStruct
{
public int int_var;
public float float_var;
public string char_var;
public Vector vector_var;
public UnmanagedStruct(int i, float f, string s, Vector vec)
{
this.int_var = i;
this.float_var = f;
this.char_var = s;
this.vector_var = vec;
}
}
class UnmanagedDllCallTest
{
[DllImport("unmanageddll.dll", EntryPoint = "unmanagedstruct_summary")]
public static extern void unmanagedstruct_summary([Out]UnmanagedStruct[] usList, int length);
static void Main(string[] args)
{
UnmanagedStruct[] usList = new UnmanagedStruct[1];
usList[0] = new UnmanagedStruct(1, 1.0f, "aa", new Vector(10, 1));
usList[1] = new UnmanagedStruct(2, 2.0f, "ba", new Vector(20, 2));
UnmanagedDllCallTest.unmanagedstruct_summary(usList, 2);
}
And the output is as following:
unmanaged_struct summary:
0
1.12104e-044
Unhandled Exception:
System.AccessViolationException:
Attempted to read or write protected
memory. This is often an indication
that other memory is corrupt. at
callunmanageddll.UnmanagedDllCallTest.unmanagedstruct_summary(UnmanagedStr
uct[] usList, Int32 length) at
callunmanageddll.Program.Main(String[]
args) in c:\users\dynaturtle\docume
nts\visual studio
2010\Projects\callunmanageddll\callunmanageddll\Program.cs:lin
e 68
The C++ dll is OK as I have written test in C++ and the function works well. I have read this thread but it seems the solution didn't work in my case. Any suggestions? Thanks in advance!
Use Marshal.PtrToStructure. There is a sample here.
So you would have to change the signature of the method from out structure array to out IntPtr. However, you need to know the size of the buffer being passed out.
public struct Vector
{
public float x;
public float y;
}
public struct UnmanagedStruct
{
public int int_var;
public float float_var;
public string char_var;
public Vector vector_var;
}
class UnmanagedDllCallTest
{
[DllImport("unmanageddll.dll", EntryPoint = "unmanagedstruct_summary")]
public static extern void unmanagedstruct_summary([Out] IntPtr ptr, int length);
static void Main(string[] args)
{
for(int i=0; i<length; i++)
{
UnmanagedStruc st;
Marshal.PtrToStructure(ptr, st);
// increment ptr and move forward
}
}
First: Vector and UnmanagedStruct should be structs, not classes.
JIC I'd share my approach. Perhaps this is not an expected answer by at one time I spend a time to resolve my issue.
I have the following structure to expose some data from DLL.
//C++ code
struct State
{
const wchar_t * name;
unsigned int state;
};
APIENTRY bool get_states(H_PRCSR, MacroState *, const int sz); //pay attention, function accepts already allocated array and size for it
To accept this data From C++ I can do this way
std::vector<State> states(desired_size);
get_states(hparser, &states[0], states.size());
To do the same on C# I used the following way
//C#
[StructLayout(LayoutKind.Sequential)]
public struct Status
{
public IntPtr name;
public uint state;
public string getName()
{
if (name == IntPtr.Zero) return "<no-value>";
return Marshal.PtrToStringUni(name);
}
}
//And import function...
[DllImport(dll, CallingConvention = CallingConvention.Winapi)]
private static extern bool get_states(IntPtr p, [Out]MacroFlag[] flags, int flags_size);
//And simple decoder
public static Status[] getAll(IntPtr p, int size)
{
var results = new Status[size];
get_states(p, results, size);
return results;
}
As, I saw the are different approaches to do this. This is one of them. And it works for me. Perhaps, this post will not resolve the issue but will be a good point to start