|
memcpy Access violation 0xC0000005
I wrote a code using libcurl and opencv, in wich i create two threads.
For the thread creation i used a class, called Streaming.
This class has a method, stream(), that can take an image, via Curl, from an axis camera, and then put this buffer in an Iplimage .
When i make this operation if i have one thread there is no problem, all works.
But when i have more then one thread i got a Access Violation etc... in the memcpy.
here it's ALL the code
#include "stdafx.h"
#include <stdio.h>
#include <string> // for STL string class
#include <windows.h> // for HANDLE
#include <process.h> // for _beginthread()
#include <fstream>
#include <cv.h>
#include <cvaux.h>
#include <cxcore.h>
#include <highgui.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include <iostream>
class Streaming
{
private:
const char* url;
public:
const char* window;
Streaming(const char *arg)
{
url = arg;
}
//This is a tricky static method to access the thread class
static unsigned __stdcall ThreadStaticEntryPoint(void * pThis)
{
Streaming * pthX = (Streaming*)pThis;
pthX->stream();
return 1;
}
//This is the memory structure that will contain the image buffer
struct MemoryStruct {
unsigned char *memory;
size_t size;
};
//I realloc the arriving data
static void *myrealloc(void *ptr, size_t size)
{
if(ptr)
return realloc(ptr, size);
else
return malloc(size);
}
//This in a curl specific method called when curl is performed, to allocate the image in the chunk (see below)
static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)data;
mem->memory = (unsigned char *)myrealloc(mem->memory, mem->size + realsize + 1);
if (mem->memory) {
memcpy(&(mem->memory[mem->size]), ptr, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
}
return realsize;
}
void stream()
{ //curl error-code
CURLcode error;
//create the curl handle
CURL* curl_handle;
//create an opencv window to see the stream
cvNamedWindow(window,CV_WINDOW_AUTOSIZE);
//and the iplimage tha will be filled by memcpy
IplImage* temp=cvCreateImage( fsize, IPL_DEPTH_8U, 3);
while(true){
//declare the chunk, where data will be stored
struct MemoryStruct chunk;
chunk.memory=NULL;
chunk.size = 0;
//like sleep
cvWaitKey(100);
//here begin curl session
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl_handle, CURLOPT_HEADER,false);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
error=curl_easy_perform(curl_handle);
long resp;
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &resp);
if (resp != 200) {
printf("Connection error");
}
if (error!=CURLE_OK){
printf("\nProblemi di connessione con la telecamera.\n");
}
//all is ok, go on
else{
char* buffer=(char*) chunk.memory;
buffer += sizeof(BITMAPINFOHEADER);
//Copy a no-null buffer in the iplimage
if( chunk.memory==NULL){
printf("null");
}
else{
EXCEPTION--> memcpy(temp->imageData,buffer,temp->imageSize); <--ACCESS VIOLATION
}
if(chunk.memory){
free(chunk.memory);
}
cvShowImage(url,temp);
}
//end of curl session
curl_easy_cleanup(curl_handle);
}
cvReleaseImage(&temp);
cvDestroyWindow("Streaming");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
//Inizialize Curl
curl_global_init(CURL_GLOBAL_ALL);
//Create the first Thread
Streaming* o1 = new Streaming("http://111.111.11.11/axis-cgi/bitmap/image.bmp?resolution=160x120&compression=100");
HANDLE hth1;
unsigned uiThread1ID;
hth1 = (HANDLE)_beginthreadex( NULL, // security
0, // stack size
Streaming::ThreadStaticEntryPoint,
o1, // arg list
CREATE_SUSPENDED, // so we can later call ResumeThread()
&uiThread1ID );
if ( hth1 == 0 )
printf("Failed to create thread 1\n");
DWORD dwExitCode;
GetExitCodeThread( hth1, &dwExitCode ); // should be STILL_ACTIVE = 0x00000103 = 259
printf( "initial thread 1 exit code = %u\n", dwExitCode );
//Create the second thread. Here there is the same URL for the streaming becouse i have only 1 camera on my pc
//but there will be another URL in the real application.
Streaming * o2 = new Streaming( "http://111.111.11.11/axis-cgi/bitmap/image.bmp?resolution=160x120&compression=100");
HANDLE hth2;
unsigned uiThread2ID;
hth2 = (HANDLE)_beginthreadex( NULL, // security
0, // stack size
Streaming::ThreadStaticEntryPoint,
o2, // arg list
CREATE_SUSPENDED, // so we can later call ResumeThread()
&uiThread2ID );
if ( hth2 == 0 )
printf("Failed to create thread 2\n");
GetExitCodeThread( hth2, &dwExitCode ); // should be STILL_ACTIVE = 0x00000103 = 259
printf( "initial thread 2 exit code = %u\n", dwExitCode );
o1->window="Stream 1";
o2->window="Stream 2";
ResumeThread( hth1 );
ResumeThread( hth2 );
WaitForSingleObject( hth1, INFINITE );
WaitForSingleObject( hth2, INFINITE );
GetExitCodeThread( hth1, &dwExitCode );
printf( "thread 1 exited with code %u\n", dwExitCode );
GetExitCodeThread( hth2, &dwExitCode );
printf( "thread 2 exited with code %u\n", dwExitCode );
CloseHandle( hth1 );
CloseHandle( hth2 );
delete o1;
o1 = NULL;
delete o2;
o2 = NULL;
printf("Primary thread terminating.\n");
return 0;
}
I know it's difficult to understand for who don't know opencv and libcurl but i think i make a stupid error using threads...
So if there is someone patient and he wants to help...I'm going crazy with this!
thank you in advance
manu
Last edited by LuciWiz : 15-Nov-2008 at 10:34.
Reason: Please insert your C++ code between [cpp] & [/cpp] tags
|