I know that blocks can be passed to a instance method and the method can be written as follow,
-(void)Method:((void) (^)(float)f)
{
f(0.5);
}
Also, this method is also a valid expression.
-(void)Method:((void) (*)(float)f)
{
f(0.5);
}
I want to know that what can i pass to this method? And what is the usage of this?
Besides, I want to know that is there any obj-c equivalent of the following c# code? Because I am wondering that obj-c has function pointer or not.
public static float Sum(float x, float y)
{
return x+y;
}
public delegate float Operation(float x, float y);
public static Main()
{
Operation dSum = Sum;
Console.WriteLine(dSum(0.5, 1.5));
}
Your second Objective-C method takes a C function pointer whose addressed function has a float as input and returns nothing. It's the same as with the block:
typedef void (^ BlockType)(float);
- (void)blockMethod: (BlockType)block {
block(1.0);
}
[obj blockMethod:aBlock];
vs.
typedef void (* FuncType)(float);
- (void)funcMethod: (FuncType)func {
func(1.0);
}
[obj funcMethod:aFunc];
The difference being that a function cannot capture its surrounding state (and that a function is a function, and a block is a block.)
This doesn't require Objective-C; what you're trying to do can be translated pretty easily to straight C:
static float sum(float x, float y)
{
return x + y;
}
typedef float (*Operation)(float x, float y);
int main(int argc, char **argv)
{
Operation dSum = sum;
printf("%f\n", dSum(0.5, 1.5));
return 0;
}
That should all look pretty recognizable.
Related
I have a function that repeatedly calls another function.
The second function has a bool parameter that changes the way it behaves, so when I call the first function I want to have a parameter that specifies the way the second function behaves.
void Function1(int n, bool differentBehavior = false)
{
int a = Function2(n, differentBehavior);
int b = Function2(1, differentBehavior);
int c = Function2(2, differentBehavior);
return a + b + c;
}
int Function2(int x, bool differentBehavior)
{
if (!differentBehavior) // do something
else // do something else
}
The code itself is obviously an example (in reality the second function is called over 20 times and for code readability I would love to not have to specify the second parameter every time), but I put it there to explain what I'm currently doing. Is there no better way to achieve this?
You can introduce a local function to capture the second argument like so:
int Function1(int n, bool differentBehavior = false)
{
int func(int n) => Function2(n, differentBehavior);
int a = func(n);
int b = func(1);
int c = func(2);
return a + b + c;
}
This is called "partial function application". See more here:
https://codeblog.jonskeet.uk/2012/01/30/currying-vs-partial-function-application/
While C# doesn't support true function Currying nor first-class partial function application, you can always
use a new locally scoped function (aka a local function) to wrap your Function2 with predefined arguments... which is conceptually almost the same thing as partial application, just without referential-transparency, and awkward delegate types.
Anyway, if you want to pass the outer Function1's differentBehavior argument value to Function2 then you will need to use a closure, which will capture the variable, but this will introduce slight runtime performance complications: as a closure generally means a GC heap allocation and copying function local state from the stack onto the heap and yada yada.
However, if you're only using constant parameter values - or you're okay with using different wrappers for different predefined argument values, then you can use a static local function (requires C# 8.0 or later) which prevents you from unintentionally creating a closure.
For example:
void Function1(int n, bool differentBehavior = false)
{
// Look ma, no closure!
static int PartiallyAppliedFunc2_False(int x) => Function2( x: x, differentBehavior: false );
static int PartiallyAppliedFunc2_True(int x) => Function2( x: x, differentBehavior: true );
int a = PartiallyAppliedFunc2_False(n);
int b = PartiallyAppliedFunc2_False(1);
int c = PartiallyAppliedFunc2_True(2);
return a + b + c;
}
int Function2(int x, bool differentBehavior)
{
if (!differentBehavior) // do something
else // do something else
}
One thing to look at when a lot of parameters are being passed on the stack is whether there is some higher-level state that could be represented by a member variable of the class.
Here's some code for the most basic kind of state machine. This general approach might help solve the problem you're having:
class Program
{
enum Behaviors
{
BehaviorA,
BehaviorB,
BehaviorC,
}
static Behaviors State { get; set; }
static void Main(string[] args)
{
for (State = Behaviors.BehaviorA; State <= Behaviors.BehaviorC; State++)
{
Console.WriteLine($"Function returned { Function1(0)}");
}
int Function1(int n)
{
int a = Function2(n);
int b = Function2(1);
int c = Function2(2);
return a + b + c;
}
int Function2(int x)
{
switch (State)
{
case Behaviors.BehaviorA:
return x * 10;
case Behaviors.BehaviorB:
return x * 20;
case Behaviors.BehaviorC:
return x * 30;
default:
throw new NotImplementedException();
}
}
}
}
Im trying to return a struct from a call to a c++ dll from c#, and I get some complicated and bad behaviour that I dont understand. If my struct contains a constructor I get a memory access violation when returning it, if it is less than 12 bytes. If it is larger there is no problem. If I remove the constructor it works for all sizes. I suppose this could have something to do with my calls being c-style but I cannot find information about this. So it would be much appreciated if someone could explain or point my in a good direction of what is going on. Below are examples of code that does and does not work:
Code that works
C++ side header:
#define DLL_API __declspec(dllexport)
struct Struct4Byte
{
int x1;
};
struct Struct12Byte
{
int x1;
int x2;
int x3;
Struct12Byte() { x1 = 0; x2 = 1; x3 = 2; }
};
#ifdef __cplusplus
extern "C" {
#endif
DLL_API Struct4Byte Function4Byte(int x);
DLL_API Struct12Byte Function12Byte(int x);
#ifdef __cplusplus
}
#endif
C++ file:
Struct4Byte Function4Byte(int x)
{
Struct4Byte output;
output.x1 = 1 + x;
return output;
}
Struct12Byte Function12Byte(int x)
{
Struct12Byte output;
output.x1 = 1 + x;
output.x2 = 2 + x;
output.x3 = 3 + x;
return output;
}
On the calling side (C#) I do:
[StructLayout(LayoutKind.Sequential)]
internal struct Struct4Byte
{
public int x1;
}
[StructLayout(LayoutKind.Sequential)]
internal struct Struct12Byte
{
public int x1;
public int x2;
public int x3;
}
class Program
{
static void Main(string[] args)
{
Struct4Byte result1 = Function4Byte(3);
Struct12Byte result2 = Function12Byte(3);
}
[DllImport(#"PInvokeCheck.dll")]
internal static extern Struct4Byte Function4Byte(int x);
[DllImport(#"PInvokeCheck.dll")]
internal static extern Struct12Byte Function12Byte(int x);
}
Code that does not work
If I now change in the header file the definition of the Struct4Byte to:
struct Struct4Byte
{
int x1;
Struct4Byte(){ x1 = 0; }
};
then I get Memory Access violation.
I've noted something that might be of interest. The problem is already when calling Function4Byte. Putting a brakpoint and viewing x in the function (I put the function again below) shows that x get some random value.
Struct4Byte Function4Byte(int x)
{
Struct4Byte output;
output.x1 = 1 + x;
return output;
}
I might have found the issue. Their was a warning that I had missed that: warning C4190: 'Function4Byte' has C-linkage specified, but returns UDT 'Struct4Byte' which is incompatible with C. From this discussion it is clear that it can lead to some undefined behaviour and that the layout of the struct may change: Error in C++ code linkage: warning C4190: type has C-linkage specified, but returns UDT which is incompatible with C
So that seems explain the problem I've had.
Yea returning structs like that isn't supported and the none of Microsoft's mainline P/Invoke articles represent an example of returning structs like that. None that I read anyways.
Here's a git hub example of your project doing it the correct way.
https://github.com/ditchcode/PInvokeTesting
I found this article most helpful on the marshaling of Structs and Classes
https://learn.microsoft.com/en-us/dotnet/framework/interop/passing-structures
I think the reason is explained in the calling conventions.
x64 calling convention
User-defined types can be returned by value from global functions and static member functions. To return a user-defined type by value in RAX, it must have a length of 1, 2, 4, 8, 16, 32, or 64 bits. It must also have no user-defined constructor, destructor, or copy assignment operator. It can have no private or protected non-static data members, and no non-static data members of reference type. It can't have base classes or virtual functions. And, it can only have data members that also meet these requirements. (This definition is essentially the same as a C++03 POD type. Because the definition has changed in the C++11 standard, we don't recommend using std::is_pod for this test.) Otherwise, the caller must allocate memory for the return value and pass a pointer to it as the first argument. The remaining arguments are then shifted one argument to the right. The same pointer must be returned by the callee in RAX.
x86 calling convention
On x86 platforms, all arguments are widened to 32 bits when they are passed. Return values are also widened to 32 bits and returned in the EAX register, except for 8-byte structures, which are returned in the EDX:EAX register pair. Larger structures are returned in the EAX register as pointers to hidden return structures. Parameters are pushed onto the stack from right to left. Structures that are not PODs will not be returned in registers.
Doing what is says for x64 is a good alternative solution.
the caller must allocate memory for the return value and pass a pointer to it as the first argument
So your code would look like this
Struct4Byte Function4Byte(Struct4Byte& output, int x)
{
output.x1 = 1 + x;
}
Struct12Byte Function12Byte(Struct12Byte& output, int x)
{
output.x1 = 1 + x;
output.x2 = 2 + x;
output.x3 = 3 + x;
}
class Program
{
static void Main(string[] args)
{
Struct4Byte = Function4Byte(out var result1, 3);
Function12Byte(out var result2, 3);
}
[DllImport(#"PInvokeCheck.dll")]
internal static extern void Function4Byte(out Struct4Byte result, int x);
[DllImport(#"PInvokeCheck.dll")]
internal static extern void Function12Byte(out Struct12Byte result, intx);
}
Suppose you have two structs that have exactly the same memory layout. Is it possible to do a very fast unchecked memory cast from one to the other in C#/.NET?
//my code base
[StructLayout(LayoutKind.Sequential)]
public struct VectorA
{
float x;
float y;
float z;
}
//defined by a third party library
[StructLayout(LayoutKind.Sequential)]
public struct VectorB
{
float a;
float b;
float c;
}
//somewhere else in my code
var vectorA = new VectorA();
//then calling a method from the library
MethodFromThirdPartyLibrary((VectorB)vectorA); //compiler error
Of course it should be faster as a method that assigns the data fields and creates a new copy in memory.
Also: The 3d vector is only an example, same problem for matrices which is 16 floats and Vector2, Vector4, ...
EDIT: Improved code with more comments and better usage example.
Why would it be faster? Would it be faster in C++ than writing the copy explicitly as in C#? Remember, you only have 3 x 32-bit numbers you want to copy from one place to another, so it's not exactly a good fit for vectorization.
It's likely if you had an array of these structures that you could get some speed up using vectorized load/stores in an unrolled loop in assembler. But you've not stated that in the question.
The main overhead here is probably the method call, rather than the assignment:
static void VecAToB(ref VectorA vectorA, ref VectorB vectorB)
{
vectorB.x = vectorA.a;
vectorB.y = vectorA.b;
vectorB.z = vectorA.c;
}
You might like to try:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void VecAToB(ref VectorA vectorA, ref VectorB vectorB)
{
vectorB.x = vectorA.a;
vectorB.y = vectorA.b;
vectorB.z = vectorA.c;
}
I have made a simple class which represents a point on the Cartesian plane - the Position class, which isn't working properly. As I increment the decimal coordinates, the integer coordinates don't seem to respond. That is what the ConsolidatePosition() method is for. It seems that any Double type numbers that are passed to the MoveRelative() method are converted to an integer before being stored in a *PosPrecise, as if they had already been processed by Convert.ToInt32() (the conversion seems to follow the 'round x.5 to nearest even' rule).
My code uses literal arguments, if that makes a difference. eg. MoveRelative(0, 0.5) appears in the code.
public class Position{
public int XPos;
public int YPos;
public double XPosPrecise;
public double YPosPrecise;
public class Position{
public int XPos;
public int YPos;
public double XPosPrecise;
public double YPosPrecise;
public Position(){
XPosPrecise = 0;
YPosPrecise = 0;
ConsolidatePosition();
}
public Position(double x, double y){
XPosPrecise = x;
YPosPrecise = y;
ConsolidatePosition();
}
public void MoveRelative(double x, double y){
XPosPrecise += x;
YPosPrecise += y;
ConsolidatePosition();
}
public void MoveAbsolute(double x, double y){
XPosPrecise = x;
YPosPrecise = y;
ConsolidatePosition();
}
private void ConsolidatePosition(){
XPos = Convert.ToInt32(XPosPrecise);
YPos = Convert.ToInt32(YPosPrecise);
}
}
And here are some calls to the code. They are the only calls made for one instance of the class. They are called every 'frame' of my program. I have tested the Move() method with whole and near-whole numbers, and the phantom rounding still occurs. As it stands, the output doesn't change after many calls of Move().
public void RotateRight(){
// apply central positioning
switch(ActorDirection){
case 0:
ActorPosition.MoveRelative(-2, 1);
break;
case 1:
ActorPosition.MoveRelative(2, -2);
break;
case 2:
ActorPosition.MoveRelative(-1, 2);
break;
case 3:
ActorPosition.MoveRelative(1, -1);
break;
}
ActorSprite.RotateRight(true);
ActorDirection = (ActorDirection + 1) % 4;
}
public void Move(int direction){
while(ActorDirection != direction){
RotateRight();
}
switch (ActorDirection % 4){
case 0:
ActorPosition.MoveRelative(0, -0.5);
break;
case 1:
ActorPosition.MoveRelative(0.5, 0);
break;
case 2:
ActorPosition.MoveRelative(0, 0.5);
break;
case 3:
ActorPosition.MoveRelative(-0.5, 0);
break;
}
}
My question is, am I missing an implicit conversion here?
(This is written and compiled in C#)
My guess would be the rounding of the decimal values when converted to integers is causing the problem here (as in it's a usage problem). (double)0.99 converts to (int)0. Perhaps you're looking for Math.Round()?
SORRY ALL. The problem was that a screen-wrap function returns a new position object with integer precision, not decimal precision. This was being called every game step, and replaced the old Position object, never allowing the *PosPrecise to reach more than 0.5. When the function result was set to my object, it reset to 0. It wasn't an error in any of the above code, and Payo was correct, it was how I was using it.
This is just to satisfy my own curiosity.
Is there an implementation of this:
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return x;
}
in C#? If it exists, post the code.
I guess I should have mentioned I was looking for a "safe" implementation... Either way, the BitConverter code solves the problem. The union idea is interesting. I'll test it and post my results.
Edit:
As expected, the unsafe method is the quickest, followed by using a union (inside the function), followed by the BitConverter. The functions were executed 10000000 times, and the I used the System.Diagnostics.Stopwatch class for timing. The results of the calculations are show in brackets.
Input: 79.67
BitConverter Method: 00:00:01.2809018 (0.1120187)
Union Method: 00:00:00.6838758 (0.1120187)
Unsafe Method: 00:00:00.3376401 (0.1120187)
For completeness, I tested the built-in Math.Pow method, and the "naive" method (1/Sqrt(x)).
Math.Pow(x, -0.5): 00:00:01.7133228 (0.112034710535584)
1 / Math.Sqrt(x): 00:00:00.3757084 (0.1120347)
The difference between 1 / Math.Sqrt() is so small that I don't think one needs to resort to the Unsafe Fast InvSqrt() method in C# (or any other unsafe method). Unless one really needs to squeeze out that last bit of juice from the CPU... 1/Math.Sqrt() is also much more accurate.
You should be able to use the StructLayout and FieldOffset attributes to fake a union for plain old data like floats and ints.
[StructLayout(LayoutKind.Explicit, Size=4)]
private struct IntFloat {
[FieldOffset(0)]
public float floatValue;
[FieldOffset(0)]
public int intValue;
// redundant assignment to avoid any complaints about uninitialized members
IntFloat(int x) {
floatValue = 0;
intValue = x;
}
IntFloat(float x) {
intValue = 0;
floatValue = x;
}
public static explicit operator float (IntFloat x) {
return x.floatValue;
}
public static explicit operator int (IntFloat x) {
return x.intValue;
}
public static explicit operator IntFloat (int i) {
return new IntFloat(i);
}
public static explicit operator IntFloat (float f) {
return new IntFloat(f);
}
}
Then translating InvSqrt is easy.
Use BitConverter if you want to avoid unsafe code.
float InvSqrt(float x)
{
float xhalf = 0.5f * x;
int i = BitConverter.SingleToInt32Bits(x);
i = 0x5f3759df - (i >> 1);
x = BitConverter.Int32BitsToSingle(i);
x = x * (1.5f - xhalf * x * x);
return x;
}
The code above uses new methods introduced in .NET Core 2.0. For .NET Framework, you have to fall back to the following (which performs allocations):
float InvSqrt(float x)
{
float xhalf = 0.5f * x;
int i = BitConverter.ToInt32(BitConverter.GetBytes(x), 0);
i = 0x5f3759df - (i >> 1);
x = BitConverter.ToSingle(BitConverter.GetBytes(i), 0);
x = x * (1.5f - xhalf * x * x);
return x;
}
Otherwise, the C# code is exactly the same as the C code you gave, except that the method needs to be marked as unsafe:
unsafe float InvSqrt(float x) { ... }
Definitely possible in unsafe mode. Note that even though in the Quake 3 source code the constant 0x5f3759df was used, numerical research showed that the constant 0x5f375a86 actually yields better results for Newton Approximations.
I don't see why it wouldn't be possible using the unsafe compiler option.