I was wondering if the implementation of setjmp/longjmp is possible in Python? If not, is there any equivalent alternative?
#include <setjmp.h>
#include <stdio.h>
jmp_buf env;
void fl(void);
void f2(void);
int main(void)
{
if (setjmp(env) == 0)
printf("setjmp returned 0\n");
else {
printf("Program terminates: longjmp called\n");
return 0;
}
f1();
printf("Pregram terminates normally\n");
return O;
}
void f1(void)
{
printf("f1 begins\n");
f2();
printf("f1 returns\n");
}
void f2(void)
{
printf("f2 begins\n");
longjmp(env, 1);
printf("f2 returns\n");
}
Python demands another approaches because direct use of longjmp isn't safe for Python's stack. Use greenlet:
from greenlet import greenlet
def test1():
print 12
gr2.switch()
print 34
def test2():
print 56
gr1.switch()
print 78
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
Related
I want to use a function that requires me to pass to it as a parameter a void pointer to beginning of a block of memory. The data has to be contiguous in memory for this function to work correctly.
Right now my data is stored in a IVector<IInspectable>. Looking at the memory layout of this IVector in the debugger I see that there is 28 bytes between my data. Which I think are the 7 function pointers from IUnknown and IInspectable. How can I get the underlying contiguous memory allocation of my data?
UPDATE:
Here is the solution I came up with.
Instead of using the IVector<IInspectable> I created a custom vector using the winrt::vector_base as recommended here: https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/collections
and I wrapped it in a windows runtime component so that I can use this custom vector from C#.
It looks like this:
MyVector.idl
namespace RuntimeComponent1
{
[default_interface]
runtimeclass MyVector
{
MyVector();
void Append(IInspectable in_val);
}
}
MyVector.h
// MyVector.h
#pragma once
#include "MyVector.g.h"
namespace winrt::RuntimeComponent1::implementation
{
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
struct _MyVector :
implements<_MyVector, IVector<int>, IVectorView<int>, IIterable<int>>,
winrt::vector_base<_MyVector, int>
{
auto& get_container() const noexcept
{
return m_values;
}
auto& get_container() noexcept
{
return m_values;
}
private:
std::vector<int> m_values{};
};
struct MyVector : MyVectorT<MyVector, _MyVector>
{
MyVector() = default;
void Append(Windows::Foundation::IInspectable const& in_val);
};
}
namespace winrt::RuntimeComponent1::factory_implementation
{
struct MyVector : MyVectorT<MyVector, implementation::MyVector>
{
};
}
MyVector.cpp
#include "pch.h"
#include "MyVector.h"
using namespace winrt;
namespace winrt::RuntimeComponent1::implementation
{
void MyVector::Append(Windows::Foundation::IInspectable const& in_val)
{
base_type::Append(winrt::unbox_value<int>(in_val));
}
}
Example usage:
C#
MyRuntimeComponent.MyVector my_vec = new RuntimeComponent1.MyVector();
my_vec.Append(2);
my_vec.Append(4);
MyRuntimeComponent.MyControl my_control = new RuntimeComponent0.MyControl();
my_control.do_stuff_with_contiguous_memory(my_vec);
C++
void MyControl::do_stuff_with_contiguous_memory(RuntimeComponent1::MyVector const& in_data)
{
// Yay data is contiguous
auto contiguous_data = in_data.as<MyVector>()->get_container().data();
}
The end result is that I can pass data from C# to C++/WinRT and the data will be contiguous in C++, which fixes my original problem. It works but I wonder if there might be a simpler / better way?
/* There is something wrong with the function delete_back(); I think something wrong with the remove function 3 parts.
Also remove_ele() I do not how to do it, thanks.
why I use the same method to delete element does not work
*/
#include <iostream>
using namespace std;
template<class T>
class doulinked
{
private:
doulinked *head;
doulinked *tail;
doulinked *prev;
doulinked *next;
T data;
public:
doulinked()
{
head=tail=prev=next=NULL;
T data;
}
void Inlist (doulinked *head);
void add(T d);
void insert_node();
void remove(doulinked* v);
void push_tail(T d);
void delete_front();
void delete_back();
void remove_ele (T d);
template <class U>
friend ostream & operator<<(ostream & os, const doulinked<U> & dll);
};
template<class U>
ostream & operator<<(ostream & os,const doulinked<U> & dll)
{
doulinked<U> * tmp = dll.head;
while (tmp)
{
os << tmp->data << " ";
tmp = tmp->next;
}
return os;
}
template<class T>
void doulinked<T>::add(T d)
{
doulinked *n = new doulinked;
n->data=d;
if( head == NULL)
{
head = n;
tail = n;
}
else
{
head->prev = n;
n->next = head;
head = n;
}
}
template<class T>
void doulinked<T>::push_tail(T d)
{
doulinked *n = new doulinked;
n->data=d;
if( tail == NULL)
{
head = n;
tail = n;
}
else
{
tail->next = n;
n->prev = tail;
tail = n;
}
}
template <class T>
void doulinked<T>::delete_front()
{
remove(head);
}
template <class T>
void doulinked<T>::delete_back()
{
remove(tail);
}
template <class T>
void doulinked<T>::remove(doulinked* v)
{
if(v->prev!=NULL && v->next!=NULL)
{
doulinked* p = v->prev;
doulinked* n = v->next;
p->next = n;
n->prev = p;
delete v;
}
else if(v->prev==NULL && v->next!=NULL)
{
doulinked* n =v->next;
head->next = n;
n->prev = head;
delete head;
head=n;
}
else if(v->prev!=NULL && v->next==NULL) // have some wrong with this loop;
{
doulinked* p=v->prev;
p->next=tail;
tail->prev=p;
delete tail;
tail=p;
}
}
template <class T>
void doulinked<T>::remove_ele(T d) // have some wrong with this loop
{
if(head->data==d)
{
remove(head);
head=head->next;
}
else
head=head->next;
}
int main()
{
doulinked<int> dll;
dll.add(5123);
dll.add(1227);
dll.add(127);
dll.push_tail(1235);
dll.push_tail(834);
dll.push_tail(1595);
dll.delete_front();
//dll.delete_back();
//dll.remove_ele(834);
cout<<dll<<endl;
system("pause");
}
Your design is a little confused.
The traditional C++ way to design a linked list (like std::list) has separate node and list classes, instead of a single class that acts as both:
template <typename T> struct node {
node *prev, *next;
};
template <typename T> struct list {
node *head, *tail;
};
If you want to just pass around node pointers, that's fine—but then you have to pass around node pointers, not node objects. And the mutator functions have to return a pointer as well—if you call delete_front on the head node, you've now got a reference to a deleted node; you need its next or you've lost any reference to the list. Since the constructor has to return a pointer, you can't use a real public constructor; you want a static factory method instead. And so on.
You also have to be consistent about whether there's a "sentinel node" before the head (and after the tail) or not. If you're creating a sentinel in your constructor—as you are doing—new nodes inserted at the end(s) need to point at the sentinel(s)—which you aren't doing.
Also, the whole head/tail notion you're using is wrong for a node API. (Also, it's incredibly confusing to mix and match names from different styles—you've got add matching delete_front and push_tail matching delete_back…) To have a push_tail method, you either have to walk the entire list (making it O(N)), or you have to have every node hold the tail pointer (making any list change O(N)), or you have to make the head hold a tail pointer and the tail hold a head pointer.
The last one works (it wastes a couple of pointers for every node when only one node needs each, but that rarely matters). But it gets confusing to think about.
It's actually a lot simpler to just create a circular list, where the head's prev points at the tail (or sentinel) instead of 0, and the tail's next points at the head (or sentinel) instead of 0. This gets you all the advantages of a separate list class, without needing that class—if you have a pointer to the head, that's all you need to refer to the entire list (because node is the head and node->prev is the tail, or or similarly if you have a sentinel).
Also, your constructor doesn't make much sense:
doulinked()
{
head=tail=prev=next=NULL;
T data;
}
This creates a local default-constructed T variable named data, and then… does nothing with it. You probably wanted to set data to something. And you probably wanted to use initializers for this. And in that case, you don't need to do anything, because that's already the default.
And I'm not sure what Inlist is even supposed to do.
As for remove_ele(T d), presumably you want to remove the first element whose data == d, right? If you write a find method first, then it's trivial: remove(find(d)). (I'm assuming that find throws an exception; if you want find to return null or the sentinel or something else instead, and remove_ele to return true or false, obviously you need one more line to check whether the find worked.)
If you don't know how to write a find method… well, that's kind of the whole point of a linked list, there's a trivial recursive definition for all traversal functions, including find:
node *node::find(T d) {
if (data == d) { return this; }
if (next) { return next->find(d); }
return 0;
}
Anyway, I think rather than try to bang on your code until it works, you should look at existing implementations of the various designs until you understand the differences, then pick the design you want and try to implement that.
I have a third-party C library that provides this header:
//CLibrary.h
#include <Windows.h>
#include <process.h>
typedef void (WINAPI *CLibEventCallback)(int event, void *data);
__declspec(dllexport) bool CLibStart (CLibEventCallback callback, void *data);
// CLibrary.c -- sample implementation
static CLibEventCallback cb;
void _cdecl DoWork (void *ptr)
{
for (int i = 0; i < 10; ++i)
{
cb (i*i, ptr);
Sleep (500);
}
}
__declspec(dllexport) bool CLibStart (CLibEventCallback callback, void *data)
{
cb = callback; // save address for DoWork thread...
_beginthread (DoWork, 0, data);
return true;
}
I need to create a C++/CLI class that can call CLibStart and provide a class method as the function pointer. As suggested below, this needs to be done with GetFunctionPointerForDelegate. Because the delete constructor includes 'this' and doesn't require a static method, I don't need to pass 'this' into CLibStart.
using namespace System;
using namespace System::Runtime::InteropServices;
namespace Sample {
public ref class ManagedClass
{
delegate void CLibraryDelegate (int event, void *data);
private:
CLibraryDelegate^ managedDelegate;
IntPtr unmanagedDelegatePtr;
int someInstanceData;
public:
ManagedClass()
{
this->managedDelegate = gcnew CLibraryDelegate(this, &ManagedClass::ManagedCallback);
this->unmanagedDelegatePtr = Marshal::GetFunctionPointerForDelegate(this->managedDelegate);
this->someInstanceData = 42;
}
void Start ()
{
// since the delegate includes an implicit 'this' (as static function is not needed)
// I no longer need to pass 'this' in the second parameter!
CLibStart ((CLibEventCallback) (void *) unmanagedDelegatePtr, nullptr);
}
private:
void Log (String^ msg)
{
Console::WriteLine (String::Format ("someInstanceData: {0}, message: {1}", this->someInstanceData, msg));
}
void ManagedCallback (int eventType, void *data)
{
// no longer need "data" to contain 'this'
this->Log (String::Format ("Received Event {0}", eventType));
}
};
}
All of this compiles and runs fine using this C# tester:
using System;
using Sample;
namespace Tester
{
class Program
{
static void Main(string[] args)
{
var mc = new ManagedClass();
mc.Start();
Console.ReadKey();
}
}
}
Sample output:
Received Event 0
Received Event 1
Received Event 4
Received Event 9
Received Event 16
Received Event 25
Received Event 36
Received Event 49
Received Event 64
Received Event 81
Outstanding questions:
I have this feeling that I need to use gcroot and/or pin_ptr? If
so, how? where?
Thanks.
gcroot should be in place where ref class stores delegate, like:
gcroot<CLibraryDelegate^> managedDelegate;
I have the below C struct that has a couple nested structures that have proven to be difficult to deal with using my knowledge of SWIG. Everything below is easily wrapped by SWIG execept for saddr (C socket address) and mac[6] (C array representing a MAC address). Since SWIG gives me the pointer value (SWIGTYPE_p_unsigned_char and SWIGTYPE_p_sockaddr), I would like to somehow call a helper C function to convert the pointer to a char*. I have the helper function, but I don't know the best way to plug this into SWIG. Is there any way to configure the getMac() and getSaddr() to call the helper function?
C Structure Trying To Wrap:
%rename (Details) details_t_;
typedef struct details_t_ {
uint16_t code;
char *name;
**sockaddr *saddr;**
uint32_t saddr_len;
uint8_t flag;
ios_boolean is_child;
**unsigned char mac[6];**
} details_t;
Generated Java Code:
public void setMac(SWIGTYPE_p_unsigned_char value) {
TestJNI.Details_mac_set(swigCPtr, this, SWIGTYPE_p_unsigned_char.getCPtr(value));
}
public SWIGTYPE_p_unsigned_char getMac() {
long cPtr = TestJNI.Details_mac_get(swigCPtr, this);
return (cPtr == 0) ? null : new SWIGTYPE_p_unsigned_char(cPtr, false);
}
public void setSaddr(SWIGTYPE_p_sockaddr value) {
TestJNI.Details_saddr_set(swigCPtr, this, SWIGTYPE_p_sockaddr.getCPtr(value));
}
public SWIGTYPE_p_sockaddr getSaddr() {
long cPtr = TestJNI.Details_saddr_get(swigCPtr, this);
return (cPtr == 0) ? null : new SWIGTYPE_p_sockaddr(cPtr, false);
}
Proposed SWIG.i Changes:
%module Test
%rename (realId) details_t_::mac;
%typemap(javacode) struct details_t_ %{
public String getMac() {
return Test.getMacAddressAsString(this);
//this is a pointer to details_t_ struct
}
%};
%rename (Details) details_t_;
typedef struct details_t_ {
uint16_t code;
char *name;
**sockaddr *saddr;**
uint32_t saddr_len;
uint8_t flag;
ios_boolean is_child;
**unsigned char mac[6];**
} details_t;
You can do this with a javacode typemap, e.g.:
%module test
%rename (realId) Sample::id;
%typemap(javacode) struct Sample %{
public byte getId() {
return 100-getRealId(); // Transform the real call
}
public void setId(byte value) {
setRealId(value+100);
}
%};
struct Sample {
char id;
};
Renames the generated getId() and setId(), but provides a Java get/set which can be written in terms of the SWIG generated (but renamed) one. You might want to make the SWIG generated ones private though.
I have written code that allows one to traverse mapped data in the order it was entered.
The solution I coded a couple of times was:
Given a keytype, K, and and data type, D,
std::map
std::vector
When one wanted to randomly find a data entry, use map.find(K). When one wanted to traverse the map in entry order, use std::vector::iterator (begin(), end()].
This was fine, but as an exercise, I wanted to write this 'OrderedMap' as an STL compliant container. I also have (stripped down to this discussion):
template <typename K, typename D>
class OrderedMapValue
{
private:
K first_ref;
std::map<K,size_t>& m;
std::vector<D>& v;
public:
const K& first
D& second
assignment operator=(const D& data)
{
std::map<K,size_t>::const_iterator iter = m.find(first_ref);
v[iter.second] = data; // error checking of iter stripped
}
};
Further assuming
template <typename K, typename D>
class OrderedMap
{
public:
typename OrderedMapValue<K,D>& OrderedMap<K,D>::operator[](const K&);
// snip...
};
class MyClass
{
public:
MyClass(std::string s) : _my_data(s) {}
private:
std::string _my_data;
};
The following code works:
OrderedMap<std::string,MyClass*> omap;
omap["MyKey"] = new MyClass("dummy");
However, this code does not:
OrderedMap::iterator iter = omap.find("MyKey");
MyClass * obj = iter->second;
delete obj;
iter->second = new MyClass("dummy");
Assuming I have done something
a) Structurally silly or
b) Unnecessarily complex, how should this be done?
I realize that I'm likely reinventing the wheel here, but again, this effort is mainly to increase my knowledge of STL containers, their design patterns and proper use.
Thanks in advance for any insights,
I don't have a compiler right now to test this, so there could be errors, but I think you want it more like:
template <typename K, typename D>
class OrderedMap
{
private:
std::map<K,size_t> &m;
std::vector<D> &v;
public:
typename pair<K,D> TYPE;
TYPE& operator[](const K &k)
{
return v[ m[ k ]];
}
TYPE& operator[](size_t idx)
{
return v[ idx ];
}
pair<iterator,bool> insert( const TYPE& pair )
{
map<K, size_t>::const_iterator iter;
iter = m.find( pair.first );
if( iter != m.end() )
return make_pair( v[ iter.second], false );
m.insert( make_pair( pair->first, v.size() ));
v.push_back( pair->second );
return make_pair( v.last() , inserted );
}
iterator &begin()
{
return v.begin();
}
// etc
};
In OrderedMapValue::operator=, you have:
std::map<K,size_t>::const_iterator iter = m.find(first_ref);
What is first_ref? The code doesn't reference it (no pun intended) elsewhere. It looks to me like it might be a vestige from an older implementation, replaced elsewhere by the public member
const K& first.
Could this be the problem?
EDIT from the comments: The code doesn't show that first_ref is initialized anywhere; so for all I can tell, the call to m.find(first_ref) is searching for an empty string, rather than the key for the OrderedMapValue.