在 C 中通过引用将值从一个函数传递到另一个函数
Passing Values from One Function to Another in C by reference
我需要一个从文件中读取数据块的程序。该块有一个 dwData
和 dwLength
字段。 dwLength
字段是 sizeof dwData
,就像 strlen
是字符串一样。
此程序中的问题是 readChunk0
无法获得从 readChunk
初始化的 dwLength
值。 dwLength
值在 readChunk
中正常,因为 cvar.mbsz
消息正确显示它(字符串的消息框)。
为什么我无法在测试函数中读取 dwLength
?为什么 dwData
可以正常通过,但 dwLength
没有。
//////////////////////////////////////////////////////////////
// read contents of a chunk in dwData
// and dwLength value in a hex file
//
//////////////////////////////////////////////////////////////
DWORD readChunk(DWORD dwData, DWORD dwLength, TCHAR ccSymbol[6]){
HWND hWnd=cvar.get_hwnd();
STRCK strform;//readChunk
strform.cksize=sizeof(STRCK);
// strform.ccSymbol=
// strform.ckmaxsize=200;
// strform.nextck=0x4;
//open file in HMMIO mode
//filename is a common one
cchmmio=mmioOpen("vocer.hex", NULL, MMIO_READ|MMIO_DENYNONE);
if (cchmmio==NULL){
MessageBox(hWnd, "eroare 1 mmioOpen", "titlu", 0);
return 1;
};
MMCKINFO lpckParent={0,0,mmioFOURCC('W','A','V','E'),0,0};
lpckParent.fccType=mmioFOURCC('W','A','V','E');
lpckParent.cksize=sizeof(MMCKINFO)+sizeof(STRCK);
HRESULT hr=mmioDescend(cchmmio, (LPMMCKINFO)&lpckParent, NULL, MMIO_FINDCHUNK);
if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){//&(hr!=MMIOERR_CHUNKNOTFOUND)){
MessageBox(hWnd, "eroare 2", "titlu", 0);
return 2;
};
if (hr==MMIOERR_CHUNKNOTFOUND){
MessageBox(hWnd, "eroare 3 WAVE CHUNKNOTFOUND", "titlu", 0);
return 3;
};
MMCKINFO mmckinfo;
mmckinfo.ckid=mmioStringToFOURCC(ccSymbol, 0);
//if you find the symbol, read dwData chunk;
hr=mmioDescend(cchmmio, &mmckinfo, &lpckParent, MMIO_FINDCHUNK);
if (hr==MMIOERR_CHUNKNOTFOUND){
MessageBox(hWnd, "4) eroare fatala. ccSymbol not found", "titlu", 0);
return 4;
};
if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
MessageBox(hWnd, "eroare 5", "titlu", 0);
return 5;
}
dwLength=(DWORD*)mmckinfo.cksize;
// memcpy(&dwLength, &mmckinfo.cksize, 2);
hr=mmioRead(cchmmio, (LPSTR)&dwData, (LONG)dwLength);
if (hr!=(LONG)dwLength){
MessageBox(hWnd, "eroare 6 mmioRead ccSymbol", "titlu", 0);
return 6;
};
hr=mmioClose(cchmmio, 0);
if (hr!=MMSYSERR_NOERROR){
MessageBox(hWnd, "eroare 9 mmioClose", "titlu", 0);
return 9;
};
//ok
// cvar.mbsz((LPSTR)dwData, "titlu", 0);//display dwData contents
// cvar.mbsz("strlen(szData):", "titlu", strlen((LPSTR)dwData));//display szData value
cvar.mbsz("(DWORD)dwLength:", "titlu", (DWORD)dwLength);//display length read
return 0;
}
// Test Function///////////////////////////////////////
// open vocer.hex file
// read a ccSymbol chunk and return the
// dwData and dwLength values
//
void readChunk0(void){
HWND hWnd=cvar.get_hwnd();
DWORD dwData=(DWORD)calloc(200, sizeof(DWORD));
DWORD dwLength=2;
TCHAR cc[6]="x002";
HRESULT hr=readChunk((DWORD*)&dwData, (DWORD*)&dwLength, cc);
if (hr){
cvar.mbsz("eroare la revenirea din readChunk:", "titlu", hr);
return;
};
//result is read in dwData
//and has dwLength length
//display the length of the message: dwLength (2 methods)
//and contents of the dwData buffer
TCHAR sztemp[256];
sprintf(sztemp, "%d", dwLength);
MessageBox(hWnd, sztemp, "titlu", 0);
cvar.mbsz("(DWORD)dwlength:", "titlu", (DWORD)dwLength);
MessageBox(hWnd, (LPSTR)dwData, "titlu:", 0);
}
编辑
谢谢 Diegos,感谢您提出的又快又好的建议。我把它放在一起告诉你。
让我写下我目前所理解的。
//////////////////////////////////////////////////////////////
// read contents of a iData chunk and iLength value
// in vocer.hex RIFF file
//
//////////////////////////////////////////////////////////////
DWORD readChunk(int* iData, int* iLength, LPSTR ccSymbol){
HWND hWnd=cvar.get_hwnd();
if (!PathFileExists(szName0))
strcpy(szName0, "vocer.hex");
cchmmio=mmioOpen(szName0, NULL, MMIO_READ|MMIO_DENYNONE);
MMCKINFO lpckParent={0};
lpckParent.fccType=mmioFOURCC('W','A','V','E');
HRESULT hr=mmioDescend(cchmmio, (LPMMCKINFO)&lpckParent, NULL, MMIO_FINDCHUNK);
if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
MessageBox(hWnd, "eroare 2", "titlu", 0);
return 2;
};
if (hr==MMIOERR_CHUNKNOTFOUND){
MessageBox(hWnd, "eroare 3 WAVE CHUNKNOTFOUND", "titlu", 0);
return 3;
};
MMCKINFO mmckinfo={0};
mmckinfo.ckid=mmioStringToFOURCC(ccSymbol, 0);
//daca ai gasit symbolul, citeste chunkul dwData;
hr=mmioDescend(cchmmio, &mmckinfo, &lpckParent, MMIO_FINDCHUNK);
if (hr==MMIOERR_CHUNKNOTFOUND){
MessageBox(hWnd, "eroare 4. ccSymbol not found", "titlu", 0);
return 4;
};
if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
MessageBox(hWnd, "eroare 5", "titlu", 0);
return 5;
};
// memcpy((int*)iLength, (long*)mmckinfo.cksize, 2);
iLength[0]=mmckinfo.cksize;
TCHAR sztemp2[256];
TCHAR* sztemp=(TCHAR*)calloc(iLength[0]+1, sizeof(TCHAR));
hr=mmioRead(cchmmio, (LPSTR)sztemp, (long)iLength[0]);
sprintf(sztemp2, "iData:%s\nmmioRead:%d", (LPSTR)sztemp, hr);
MessageBox(hWnd, (LPSTR)sztemp2, "titlu", 0);
if (hr!=iLength[0]){
cvar.mbsz("valoare dwLength:", "titlu", (long)iLength[0]);
MessageBox(hWnd, "eroare 6 mmioRead ccSymbol", "titlu", 0);
return 6;
};
for(int i=0; i<iLength[0]; i++)
iData[i]=sztemp[i];
// memcpy(&iData[i], &sztemp[i], 1);
hr=mmioClose(cchmmio, 0);
return 0;
}
//Functie Test//////////////////////////////////////////
// open vocer.hex file
// read ccSymbol chunk and return
// dwData of dwLength
//
//////////////////////////////////////////////////////////////
void readChunk00(void){
HWND hWnd=cvar.get_hwnd();
int* iLength=(int*)calloc(1, sizeof(int));
int* iData=(int*)calloc(200, sizeof(int));
TCHAR ccSymbol[6]="0x02";
TCHAR sztemp[200];//=(TCHAR*)calloc(iLength[0]+2, sizeof(TCHAR));
HRESULT hr=readChunk((int*)iData, (int*)iLength, ccSymbol);
wsprintf(sztemp, "dwLength:%d\niData:%s", iLength[0], (LPSTR)&iData[0]);
MessageBox(hWnd, (LPSTR)sztemp, "titlu", 0);
strcpy(sztemp, "");
MessageBox(hWnd, "inainte de for", "titlu", 0);
for(int i=0; i<iLength[0]; i++){
// strcat(sztemp,(LPSTR)&iData[i]);
sztemp[i]=(TCHAR)&iData[i];
};
TCHAR* sztemp2=(TCHAR*)calloc(iLength[0]+2, sizeof(TCHAR));
sprintf(sztemp2, "dwLength:%d\niData:%s", iLength[0], (LPSTR)sztemp);
// sprintf(sztemp, "dwLength:%d\niData[1]:%d", iLength[0], iData[1]);
MessageBox(hWnd, (LPSTR)sztemp2, "titlu", 0);
}
//Functie Test///////////////////////////////////////
// deschide fisierul voce.hex
// citeste un chunk ccSymbol si returneaza
// dwData de dimensiune dwLength
// metoda cu pointer
void readChunk0(void){
HWND hWnd=cvar.get_hwnd();
LPSTR ccSymbol="0x02";
int* dwLength=(int*)calloc(1, sizeof(int));
HGLOBAL hData=GlobalAlloc(GHND, (int)dwLength);
if (hData==0){
cvar.mbsz("eroare la GlobalAlloc:", "titlu", GetLastError());
return;
};
int* iData=(int*)GlobalLock(hData);
if (iData==0){
cvar.mbsz("eroare la GlobalLock:", "titlu", GetLastError());
return;
};
HRESULT hr=readChunk((int*)iData, (int*)dwLength, ccSymbol);
if (hr){
cvar.mbsz("eroare la revenirea din readChunk:", "titlu", hr);
return;
};
hr=GlobalUnlock(hData);
if (hr!=0){
cvar.mbsz("eroare la GlobalUnlock:", "titlu", GetLastError());
return;
};
TCHAR* sztemp=(TCHAR*)calloc(dwLength[0]+2, sizeof(TCHAR));
for(int i=0; i<dwLength[0]; i++)
sztemp[i]=iData[i];
strcat(sztemp, "[=1=]");
MessageBox(hWnd, (LPSTR)sztemp, "titlu", 0);
cvar.mbsz("(DWORD)dwLength:", "titlu", dwLength[0]);
}
我最终让它运行起来了。请下次指导,因为 OS (WINDOWS XP) 的 calloc 函数的实现方式与 GlobalAlloc 不同。我写了两个结果相同的函数,如果我错了请纠正我。函数测试 readChunk00 是用 calloc 完成的,它不能 read 由 readChunk 中的主函数完成的第一个参数 dwLength[0] 的修改。
函数 readChunk0 是为与 readChunk00 相同的目的而构建的测试函数,但现在它使用 GlobalAlloc 和系列函数,在我看来,OS.
可以更好地解释这些函数
你觉得calloc的第一个参数(dwLength[0])是不是调用hr=readChunk函数初始化不好?这个主题不是重复的。感谢您的宝贵时间:)
如果您希望修改调用者看到的值,您需要将指向 dwLength
的指针传递给 readChunk
并在函数内部取消引用它。
此外,鉴于dwData
的初始化,它的数据类型应该是DWORD*
。
编辑以了解新信息。
你的新方法还有一些问题。下面是一些代码片段,希望大家可以拼凑起来。
这是您应该如何声明您的 readChunk
函数:
DWORD readChunk(DWORD* dwData, DWORD* dwLength, TCHAR ccSymbol[6])
在函数内部,这是设置 dwLength
指向的值的方式:
*dwLength = mmckinfo.cksize;
在你的测试函数中,你是这样声明的 dwData
:
DWORD* dwData = calloc(200, sizeof(DWORD));
这就是您声明的方式 dwLength
:
DWORD dwLength;
最后,这就是将所有数据传递给 readChunk
的方式:
HRESULT hr = readChunk(dwData, &dwLength, cc);
您确实需要熟悉指针的工作原理以及参数如何按值或通过 C 中的指针间接传递。
我需要一个从文件中读取数据块的程序。该块有一个 dwData
和 dwLength
字段。 dwLength
字段是 sizeof dwData
,就像 strlen
是字符串一样。
此程序中的问题是 readChunk0
无法获得从 readChunk
初始化的 dwLength
值。 dwLength
值在 readChunk
中正常,因为 cvar.mbsz
消息正确显示它(字符串的消息框)。
为什么我无法在测试函数中读取 dwLength
?为什么 dwData
可以正常通过,但 dwLength
没有。
//////////////////////////////////////////////////////////////
// read contents of a chunk in dwData
// and dwLength value in a hex file
//
//////////////////////////////////////////////////////////////
DWORD readChunk(DWORD dwData, DWORD dwLength, TCHAR ccSymbol[6]){
HWND hWnd=cvar.get_hwnd();
STRCK strform;//readChunk
strform.cksize=sizeof(STRCK);
// strform.ccSymbol=
// strform.ckmaxsize=200;
// strform.nextck=0x4;
//open file in HMMIO mode
//filename is a common one
cchmmio=mmioOpen("vocer.hex", NULL, MMIO_READ|MMIO_DENYNONE);
if (cchmmio==NULL){
MessageBox(hWnd, "eroare 1 mmioOpen", "titlu", 0);
return 1;
};
MMCKINFO lpckParent={0,0,mmioFOURCC('W','A','V','E'),0,0};
lpckParent.fccType=mmioFOURCC('W','A','V','E');
lpckParent.cksize=sizeof(MMCKINFO)+sizeof(STRCK);
HRESULT hr=mmioDescend(cchmmio, (LPMMCKINFO)&lpckParent, NULL, MMIO_FINDCHUNK);
if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){//&(hr!=MMIOERR_CHUNKNOTFOUND)){
MessageBox(hWnd, "eroare 2", "titlu", 0);
return 2;
};
if (hr==MMIOERR_CHUNKNOTFOUND){
MessageBox(hWnd, "eroare 3 WAVE CHUNKNOTFOUND", "titlu", 0);
return 3;
};
MMCKINFO mmckinfo;
mmckinfo.ckid=mmioStringToFOURCC(ccSymbol, 0);
//if you find the symbol, read dwData chunk;
hr=mmioDescend(cchmmio, &mmckinfo, &lpckParent, MMIO_FINDCHUNK);
if (hr==MMIOERR_CHUNKNOTFOUND){
MessageBox(hWnd, "4) eroare fatala. ccSymbol not found", "titlu", 0);
return 4;
};
if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
MessageBox(hWnd, "eroare 5", "titlu", 0);
return 5;
}
dwLength=(DWORD*)mmckinfo.cksize;
// memcpy(&dwLength, &mmckinfo.cksize, 2);
hr=mmioRead(cchmmio, (LPSTR)&dwData, (LONG)dwLength);
if (hr!=(LONG)dwLength){
MessageBox(hWnd, "eroare 6 mmioRead ccSymbol", "titlu", 0);
return 6;
};
hr=mmioClose(cchmmio, 0);
if (hr!=MMSYSERR_NOERROR){
MessageBox(hWnd, "eroare 9 mmioClose", "titlu", 0);
return 9;
};
//ok
// cvar.mbsz((LPSTR)dwData, "titlu", 0);//display dwData contents
// cvar.mbsz("strlen(szData):", "titlu", strlen((LPSTR)dwData));//display szData value
cvar.mbsz("(DWORD)dwLength:", "titlu", (DWORD)dwLength);//display length read
return 0;
}
// Test Function///////////////////////////////////////
// open vocer.hex file
// read a ccSymbol chunk and return the
// dwData and dwLength values
//
void readChunk0(void){
HWND hWnd=cvar.get_hwnd();
DWORD dwData=(DWORD)calloc(200, sizeof(DWORD));
DWORD dwLength=2;
TCHAR cc[6]="x002";
HRESULT hr=readChunk((DWORD*)&dwData, (DWORD*)&dwLength, cc);
if (hr){
cvar.mbsz("eroare la revenirea din readChunk:", "titlu", hr);
return;
};
//result is read in dwData
//and has dwLength length
//display the length of the message: dwLength (2 methods)
//and contents of the dwData buffer
TCHAR sztemp[256];
sprintf(sztemp, "%d", dwLength);
MessageBox(hWnd, sztemp, "titlu", 0);
cvar.mbsz("(DWORD)dwlength:", "titlu", (DWORD)dwLength);
MessageBox(hWnd, (LPSTR)dwData, "titlu:", 0);
}
编辑
谢谢 Diegos,感谢您提出的又快又好的建议。我把它放在一起告诉你。
让我写下我目前所理解的。
//////////////////////////////////////////////////////////////
// read contents of a iData chunk and iLength value
// in vocer.hex RIFF file
//
//////////////////////////////////////////////////////////////
DWORD readChunk(int* iData, int* iLength, LPSTR ccSymbol){
HWND hWnd=cvar.get_hwnd();
if (!PathFileExists(szName0))
strcpy(szName0, "vocer.hex");
cchmmio=mmioOpen(szName0, NULL, MMIO_READ|MMIO_DENYNONE);
MMCKINFO lpckParent={0};
lpckParent.fccType=mmioFOURCC('W','A','V','E');
HRESULT hr=mmioDescend(cchmmio, (LPMMCKINFO)&lpckParent, NULL, MMIO_FINDCHUNK);
if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
MessageBox(hWnd, "eroare 2", "titlu", 0);
return 2;
};
if (hr==MMIOERR_CHUNKNOTFOUND){
MessageBox(hWnd, "eroare 3 WAVE CHUNKNOTFOUND", "titlu", 0);
return 3;
};
MMCKINFO mmckinfo={0};
mmckinfo.ckid=mmioStringToFOURCC(ccSymbol, 0);
//daca ai gasit symbolul, citeste chunkul dwData;
hr=mmioDescend(cchmmio, &mmckinfo, &lpckParent, MMIO_FINDCHUNK);
if (hr==MMIOERR_CHUNKNOTFOUND){
MessageBox(hWnd, "eroare 4. ccSymbol not found", "titlu", 0);
return 4;
};
if ((hr!=MMSYSERR_NOERROR)&(hr!=MMIOERR_CHUNKNOTFOUND)){
MessageBox(hWnd, "eroare 5", "titlu", 0);
return 5;
};
// memcpy((int*)iLength, (long*)mmckinfo.cksize, 2);
iLength[0]=mmckinfo.cksize;
TCHAR sztemp2[256];
TCHAR* sztemp=(TCHAR*)calloc(iLength[0]+1, sizeof(TCHAR));
hr=mmioRead(cchmmio, (LPSTR)sztemp, (long)iLength[0]);
sprintf(sztemp2, "iData:%s\nmmioRead:%d", (LPSTR)sztemp, hr);
MessageBox(hWnd, (LPSTR)sztemp2, "titlu", 0);
if (hr!=iLength[0]){
cvar.mbsz("valoare dwLength:", "titlu", (long)iLength[0]);
MessageBox(hWnd, "eroare 6 mmioRead ccSymbol", "titlu", 0);
return 6;
};
for(int i=0; i<iLength[0]; i++)
iData[i]=sztemp[i];
// memcpy(&iData[i], &sztemp[i], 1);
hr=mmioClose(cchmmio, 0);
return 0;
}
//Functie Test//////////////////////////////////////////
// open vocer.hex file
// read ccSymbol chunk and return
// dwData of dwLength
//
//////////////////////////////////////////////////////////////
void readChunk00(void){
HWND hWnd=cvar.get_hwnd();
int* iLength=(int*)calloc(1, sizeof(int));
int* iData=(int*)calloc(200, sizeof(int));
TCHAR ccSymbol[6]="0x02";
TCHAR sztemp[200];//=(TCHAR*)calloc(iLength[0]+2, sizeof(TCHAR));
HRESULT hr=readChunk((int*)iData, (int*)iLength, ccSymbol);
wsprintf(sztemp, "dwLength:%d\niData:%s", iLength[0], (LPSTR)&iData[0]);
MessageBox(hWnd, (LPSTR)sztemp, "titlu", 0);
strcpy(sztemp, "");
MessageBox(hWnd, "inainte de for", "titlu", 0);
for(int i=0; i<iLength[0]; i++){
// strcat(sztemp,(LPSTR)&iData[i]);
sztemp[i]=(TCHAR)&iData[i];
};
TCHAR* sztemp2=(TCHAR*)calloc(iLength[0]+2, sizeof(TCHAR));
sprintf(sztemp2, "dwLength:%d\niData:%s", iLength[0], (LPSTR)sztemp);
// sprintf(sztemp, "dwLength:%d\niData[1]:%d", iLength[0], iData[1]);
MessageBox(hWnd, (LPSTR)sztemp2, "titlu", 0);
}
//Functie Test///////////////////////////////////////
// deschide fisierul voce.hex
// citeste un chunk ccSymbol si returneaza
// dwData de dimensiune dwLength
// metoda cu pointer
void readChunk0(void){
HWND hWnd=cvar.get_hwnd();
LPSTR ccSymbol="0x02";
int* dwLength=(int*)calloc(1, sizeof(int));
HGLOBAL hData=GlobalAlloc(GHND, (int)dwLength);
if (hData==0){
cvar.mbsz("eroare la GlobalAlloc:", "titlu", GetLastError());
return;
};
int* iData=(int*)GlobalLock(hData);
if (iData==0){
cvar.mbsz("eroare la GlobalLock:", "titlu", GetLastError());
return;
};
HRESULT hr=readChunk((int*)iData, (int*)dwLength, ccSymbol);
if (hr){
cvar.mbsz("eroare la revenirea din readChunk:", "titlu", hr);
return;
};
hr=GlobalUnlock(hData);
if (hr!=0){
cvar.mbsz("eroare la GlobalUnlock:", "titlu", GetLastError());
return;
};
TCHAR* sztemp=(TCHAR*)calloc(dwLength[0]+2, sizeof(TCHAR));
for(int i=0; i<dwLength[0]; i++)
sztemp[i]=iData[i];
strcat(sztemp, "[=1=]");
MessageBox(hWnd, (LPSTR)sztemp, "titlu", 0);
cvar.mbsz("(DWORD)dwLength:", "titlu", dwLength[0]);
}
我最终让它运行起来了。请下次指导,因为 OS (WINDOWS XP) 的 calloc 函数的实现方式与 GlobalAlloc 不同。我写了两个结果相同的函数,如果我错了请纠正我。函数测试 readChunk00 是用 calloc 完成的,它不能 read 由 readChunk 中的主函数完成的第一个参数 dwLength[0] 的修改。
函数 readChunk0 是为与 readChunk00 相同的目的而构建的测试函数,但现在它使用 GlobalAlloc 和系列函数,在我看来,OS.
可以更好地解释这些函数你觉得calloc的第一个参数(dwLength[0])是不是调用hr=readChunk函数初始化不好?这个主题不是重复的。感谢您的宝贵时间:)
如果您希望修改调用者看到的值,您需要将指向 dwLength
的指针传递给 readChunk
并在函数内部取消引用它。
此外,鉴于dwData
的初始化,它的数据类型应该是DWORD*
。
编辑以了解新信息。
你的新方法还有一些问题。下面是一些代码片段,希望大家可以拼凑起来。
这是您应该如何声明您的 readChunk
函数:
DWORD readChunk(DWORD* dwData, DWORD* dwLength, TCHAR ccSymbol[6])
在函数内部,这是设置 dwLength
指向的值的方式:
*dwLength = mmckinfo.cksize;
在你的测试函数中,你是这样声明的 dwData
:
DWORD* dwData = calloc(200, sizeof(DWORD));
这就是您声明的方式 dwLength
:
DWORD dwLength;
最后,这就是将所有数据传递给 readChunk
的方式:
HRESULT hr = readChunk(dwData, &dwLength, cc);
您确实需要熟悉指针的工作原理以及参数如何按值或通过 C 中的指针间接传递。