Block_copy Went Missing - ios4

I have an Xcode project which includes OpenFeint as a dependency. OpenFeint has one class that makes two calls to Block_copy() and one call to Block_release(). All was well (as in, I built and ran the project a number of times without incident) until suddenly the compiler started complaining that these functions don't exist. The thing literally broke in between two builds, with no changes to the source code in between.
I have no idea where these functions could have gone, but I've attempted to work around it by providing some placeholder function prototypes, like so:
extern void* Block_copy(const void *aBlock);
extern void Block_release(const void *aBlock);
I'm not sure if those are the correct signatures (the documentation on this topic is sparse, at best), but it's the closest I've been able to find. Sadly, this just causes the linker to complain instead of the compiler.
So any ideas? Is my whole development environment screwed? If not, how do I get it working again?

Did you switch XCode or perhaps iOS (hinting at something recently released for developers). It might be that, if you switched to ARC accidentally, those functions may no longer exist (ARC isn't under NDA since it already existed and is open source).

The actual definition of Block_copy is in
/Developer/SDKs/MacOSX10.6.sdk/usr/include/Block.h
and reads
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
and _Block_copy is defined in the same file by
BLOCK_EXPORT void *_Block_copy(const void *aBlock);
Providing your own definition will not help Xcode. Has your target in XCode changed ?

A temporary workaround is to inline the entire contents of 'Block.h' in the OpenFeint source file. Strangely, trying to #include or #import the file does not work, which may be the whole of the problem.
In any case, this file should exist at /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator[VERSION].sdk/usr/include/Block.h, and the contents should be:
#ifndef _Block_H_
#define _Block_H_
#if !defined(BLOCK_EXPORT)
# if defined(__cplusplus)
# define BLOCK_EXPORT extern "C"
# else
# define BLOCK_EXPORT extern
# endif
#endif
#include <Availability.h>
#include <TargetConditionals.h>
#if __cplusplus
extern "C" {
#endif
// Create a heap based copy of a Block or simply add a reference to an existing one.
// This must be paired with Block_release to recover memory, even when running
// under Objective-C Garbage Collection.
BLOCK_EXPORT void *_Block_copy(const void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Lose the reference, and if heap based and last reference, recover the memory
BLOCK_EXPORT void _Block_release(const void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not call this function yourself.
BLOCK_EXPORT void _Block_object_assign(void *, const void *, const int)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not call this function yourself.
BLOCK_EXPORT void _Block_object_dispose(const void *, const int)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not use these variables yourself.
BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
BLOCK_EXPORT void * _NSConcreteStackBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#if __cplusplus
}
#endif
// Type correct macros
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))
#endif

Related

Inheriting a base class from Modbus static library causes invalid stack pointer on return, but works fine when using base class directly

I'm using VC++2017 to write a program to communicate with a PLC using Modbus. Ideally, I want to create a class that inherits from the MbusAsciiMasterProtocol but it's looking like that will be impossible. My current header file for it is:
#pragma once
#include "MbusAsciiMasterProtocol.hpp"
class PlcModbus
: public MbusAsciiMasterProtocol {
public:
/* Also tried without calling MbusAscii constructor and doesn't work*/
PlcModbus() : MbusAsciiMasterProtocol() {}
~PlcModbus() {}
};
and the part in the main function that uses it is
/* Doesn't work */
int dataArr[18];
PlcModbus plc;
plc.openProtocol("COM3", 19700L, 8, 1, 0);
plc.readMultipleLongInts(1, 1, dataArr, sizeof(dataArr) / sizeof(int)); // Breaks here
plc.closeProtocol();
Which throws a null pointer exception when it gets to plc.readMultipleLongInts (it successfully calls openProtocol and opens the connection). I did some digging with the debugger and found that the stack pointer after the function is called is 12 spaces away from where it was prior to the function call.
Now, if I don't inherit from MbusAsciiMasterProtocol and instead use the class directly, everything works fine.
/* Works fine */
int dataArr[18];
MbusAsciiMasterProtocol plc;
plc.openProtocol("COM3", 19700L, 8, 1, 0);
plc.readMultipleLongInts(1, 1, dataArr, sizeof(dataArr) / sizeof(int));
plc.closeProtocol();
There is no runtime error and I am able to communicate with the PLC. This makes absolutely no sense to me because up until this point I assumed that inheriting from a base class essentially gave you access to the same public and protected member functions within the base class. But this seems to imply otherwise.
I also tried to use MbusAsciiMasterProtocol as an object in PlcModbus and write wrappers around the functions I need, but that didn't work either and it gave the error "- The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."
#pragma once
#include "MbusAsciiMasterProtocol.hpp"
class PlcModbus {
public:
PlcModbus() : myModbus(MbusAsciiMasterProtocol()) {}
~PlcModbus() {}
int openProtocol(const TCHAR *portName, long baudRate, int dataBits, int stopBits, int parity) {
return myModbus.openProtocol(portName, baudRate, dataBits, stopBits, parity);
}
int readMultipleLongInts(int slaveAddr, int startRef, int *int32Arr, int refCount) {
return myModbus.readMultipleLongInts(slaveAddr, startRef, int32Arr, refCount);
}
void closeProtocol() {
myModbus.closeProtocol();
}
public:
MbusAsciiMasterProtocol &myModbus;
};
I feel there must be something going wrong with the calls to the static library based off of that error, but why it works when I use the base class and not when I inherit from it is beyond me. Any explanation about what's going on would be extremely helpful.
Cheers.
I don't know why inheriting from MbusAsciiMasterProtocol doesn't work for you.
However in your last code example where you write wrappers around functions you have one subtle error:
MbusAsciiMasterProtocol &myModbus; creates a reference to MbusAsciiMasterProtocol object.
In the constructor you are initializing it with MbusAsciiMasterProtocol() - a temporary object thus creating a reference to a temporary. This is probably the source of the errors you are getting. Remove the reference and make the object private instead of public.

Static Mutex for Class member Function : C++ 11

Referring to RAII
I can use static mutex for a critical section as:
#include <string>
#include <mutex>
#include <iostream>
#include <fstream>
#include <stdexcept>
void write_to_file (const std::string & message) {
// mutex to protect file access
static std::mutex mutex;
// lock mutex before accessing file
std::lock_guard<std::mutex> lock(mutex);
// try to open file
std::ofstream file("example.txt");
if (!file.is_open())
throw std::runtime_error("unable to open file");
// write message to file
file << message << std::endl;
// file will be closed 1st when leaving scope (regardless of exception)
// mutex will be unlocked 2nd (from lock destructor) when leaving
// scope (regardless of exception)
}
If use the same approach for a class member function such as:
class Test{
public:
void setI(int k)
{
static std::mutex mutex;
std::lock_guard<std::mutex> lock(mutex);
i=k;
}
private:
int i;
};
What are the cons and pros of above approach?
Is it more advisable to use the approach as below:
class Test
{
public:
void setI(int k)
{
std::lock_guard<std::mutex> lock(mutex);
i = k;
}
private:
int i;
std::mutex mutex;
};
which method to ensure thread safety is better?
reference 1
"Static variables declared in member functions will keep their value between function calls. There will be only one copy over all instances"
Both of your solutions is "valid", it really depends on what you want to accomplish...
static mutex variable inside member function
This solution gives you one mutex for all instances of the class. It will be effective in providing thread-safety but might not be optimal for performance if you have many objects you spread across different threads.
The mutex is also limited to only that single function so usually this makes the implementation impractical. A static private variable is usually better therefore.
private mutex variable inside class
With this solution you get one mutex per instance of your class. It will be effective to provide thread safety for your class so that multiple threads can access it. This is usually the more preferred solution as it allows different threads to access different objects at the same time.
However this will not be sufficient to protect access to static members of your class.
Most of the time you want to have a private non-static mutex inside your class.
The static mutex inside function is seems to be useful only (and only) if you're trying to access some resource only (and only) in this function.
If you'll need to add some read function to class Test (like int getI() const;) tomorrow, then you should to refactor and setI function and class Test. If you'll use mutex as a class member, then you need just to write getI's code, using mutex similar as in setI
I guess static mutex is good.
because there is one resource you want to protect.
Rather than multiple instances of class having each mutex individually, it's better to have one mutex for all since there is only one resource.
I myself just imagining as a resource like a house.
we will have one locker to lock right.
Please correct me if I am wrong anywhere :)

VC++ 2010 can access class variable vector of struct from Main() but not from class function

I have written a header file with one basic data structure.
ProdList.h
#ifndef LISTOFITEMS_H
#define LISTOFITEMS_H
struct ListOfItems
{
public:
std::string fdcustid;
std::string fdstkid;
std::string fdordisquantity;
std::string fdordsstatus; // <> 'H'
std::string fdordhtype; // <> 'A'
};
#endif /* GRANDFATHER_H */
now that I have a data structure I include it in the class definition and use the data structure "ListOfItems" in the class "ProdContainer".
ProdContainer.h
#include "ProdList.h"
class ProdContainer
{
public:
ProdContainer(void);
~ProdContainer(void);
static void SetNumberOfElements(int Elements);
std::vector<ListOfItems> Items;
}
now when i write the following in Main.
int _tmain(int argc, _TCHAR* argv[])
{
ProdContainer myobject;
myobject.Items.resize(12);
printf("The size of Items is %i \n", myobject.Items.size());
return 0;
}
All goes as expected and I get the following output.
The size of Items is 12
Which is all fine and good. However, I want to encapsulate the data within the class and only allow access through class functions.
The problem arises when I add the following code to "SetNumberOfElements" implementation.
void ProdContainer::SetNumberOfElements(int Elements)
{
Items.resize(Elements);
}
When I try to compile this "error C2228 left of '.resize' must have class/struct/union" appears and I am at a loss at what to do next.
I have searched high and low and cant seem to find any posts matching this particular problem, it's probably a schoolboy error. I've checked the MSDN site on error C2228 and as far as I can see Items is a substantiated variable of struct type ListOfItems, so I can't see why this error is appearing.
Is there a method for accessing a vector of a struct or some other aspect that I just can't see.
Please help, I am just about ready to explode.
You can only access static data from static functions. So change this
static void SetNumberOfElements(int Elements);
To this
void SetNumberOfElements(int Elements);
You cannot access non-static class members from the static function.
What you can do is to "switch" from static to non-static.
static void SetNumberOfElements( void * lParam, int Elements)
{
((ProdContainer*)lParam)->Items.resize( Elements );
}
Use it like this inside your class:
SetNumberOfELements( this, 10 );

error C3767: candidate function(s) not accessible Visual Studio 2010

I'm getting this error:
error C3767: 'phys1::point::get_prev': candidate function(s) not accessible
Here's my code
phys.h
using namespace System;
namespace phys1 {
typedef struct position{
int x;
int y;
} pos;
public ref class point{
public:
point(float speed, float gr);
public:
pos get_prev();
public:
pos get_next();
};
}
phys.cpp
// This is the main DLL file.
#include "phys.h"
using namespace System;
namespace phys1 {
...
static pos point::get_prev(){
pos point;
point.x=x;
point.y=y;
return point;
}
...
}
Is it problem with my struct, which i try to use in library? Can i build it in another way?
You are mixing C++ syntax and C++/CLI syntax. The "struct" is a native definition (a C++ one).
To declare 'struct' you should better use the "value struct" construction.
The "not accessible" error can also be due to the 'position' being implicitly declared as 'private'.
See more about managed type declarations here: http://www.codeproject.com/Articles/17741/C-CLI-in-Action-Declaring-CLR-types
If you're trying to pass values of type pos across an assembly boundary, it should be a public managed type. public value struct pos would be most appropriate for what you're doing.
Native types aren't visible across assembly boundaries by default, and the #pragma that makes them visible is more of a kludge than a real solution. Just make a proper .NET type with metadata.

LNK2001 unresolved external when importing functions from MFC DLL

I have created an MFC DLL and have exported the functions for example in the file SerialPort.h:
class CSerialPortApp : public CWinApp
{
public:
CSerialPortApp();
__declspec(dllexport) int SWrite(unsigned char* toSend, int len);
};
and in my MFC application I want to call the function in SerialInterface.h I have included the "SerialPort.h" from the DLL and called:
__declspec(dllimport) int SWrite(unsigned char* toSend, int len);
class SerialInterface
{
public:
};
for example.
I have added the SerialPort.lib file to my linker includes but when I try to compile I get
error LNK2001: unresolved external symbol "__declspec(dllimport) int __cdecl SWrite(unsigned char*, int)" (__imp_?SWrite##YAHPAEH#Z)
I am stuck as to the cause of this, I have tried rebuilding everything but nothing seems to help?
Thank you for any help!
You are using __declspec(dllexport) inside a class?
You either export global functions from the dll or whole class which may contain any functions. You don't have to export selected member functions from a class, I don't even know how that works.
It is a little strange that you are not properly exporting the SerialPort class from dll (as per your code) yet you can use it in your application and call its member function!? I am a little confused.
Well I found an alternative that works, I believe I was implementing it incorrectly.
I added a new class to my DLL that was not a CWinApp class:
class SerialPort
{
public:
__declspec(dllexport) SerialPort(void);
__declspec(dllexport) virtual ~SerialPort(void);
__declspec(dllexport) int SWrite(unsigned char* toSend, int len);
};
then included the header for this in my application and the lib and dll etc.
I then placed the included header file in the main CDialog header but importantly didn't need to import any of the functions:
#include "SerialPort.h"
class CPPUDlg : public CDialog
{
public:
CPPUDlg(CWnd* pParent = NULL); // standard constructor
SerialPort objSerialPort;
and then in my code I simply call
objSerialPort.SWrite(toSend, len);
I have not used dllimport to import the functions which I assumed I would need to but it now works!
Hope this helps anyone who may have a similar problem.

Resources