01/10/2018, 16:07
Lỗi vô cùng khó hiểu: Cannot use an expression of type 'byte*' as an argument to a dynamically dispatched operation
Mình có đoạn code này:
unsafe public Task<object> uncompress16(dynamic input)
{
var inputHexAddress = Convert.ToUInt64((string)input.inputHexAddress, 16);
if (inputHexAddress == 0) throw new ArgumentException("Hex address is in invalid form!");
var outputGetter = (Func<object, Task<object>>)input.outputGetter;
var inputArr = (byte*)(new UIntPtr(inputHexAddress).ToPointer());
var inputLen = (int)input.inputLen;
var compressedData = new UnsafeArray(inputArr, inputLen);
int size = (int)compressedData[1] + ((int)compressedData[2] << 8) + ((int)compressedData[3] << 16);
return outputGetter(size).ContinueWith<object>(uncompress16_stage2);
}
unsafe private object uncompress16_stage2(Task<object> lastTask)
{
var output = (dynamic)lastTask.Result;
var outputHexAddress = Convert.ToUInt64((string)output.outputHexAddress, 16);
if (outputHexAddress == 0) throw new ArgumentException("Hex address is in invalid form!");
var outputArr = (byte*)(new UIntPtr(outputHexAddress).ToPointer());
var outputLen = output.outputLen;
var uncompressedData = new UnsafeArray(outputArr, outputLen);
return output;
}
Kết quả là dòng này:
var uncompressedData = new UnsafeArray(outputArr, outputLen);
Báo lỗi:
Cannot use an expression of type 'byte*' as an argument to a dynamically dispatched operation.
Nhưng dòng này:
var compressedData = new UnsafeArray(inputArr, inputLen);
Lại không sao cả:
Đây là class UnsafeArray:
public class UnsafeArray
{
unsafe private byte* _array;
unsafe private int _len;
unsafe public UnsafeArray(byte* array, int len)
{
if (array == null) throw new NullReferenceException("Array is null!");
if (len < 0) throw new ArgumentOutOfRangeException("Array length cannot be negative!");
this._array = array;
this._len = len;
}
unsafe public byte this[int key]
{
get
{
if (key < 0 && key >= _len) throw new ArgumentOutOfRangeException("Index of array is out of bound.");
return _array[key];
}
set
{
if (key < 0 && key >= _len) throw new ArgumentOutOfRangeException("Index of array is out of bound.");
_array[key] = value;
}
}
}
Bài liên quan
Google cái lỗi CS1978 ra thớt này bên SO: https://stackoverflow.com/questions/5418428/error-cs1978-cannot-use-an-expression-of-type-uint-as-an-argument-to-a-dynam
(đưa lỗi đưa luôn cái error code lên đưa cái error message ko google mãi ko ra @_@)
có người bảo là xài đỡ boxing pointer:
vậy thay vì truyền
byte*
vào ctor của UnsafeArray bây giờ ta truyền thẳngUIntPtr
luôn:compile đuợc nhưng chạy đúng hay ko thì ko biết @_@
Truyền IntPtr hoặc UIntPtr vào ctor, sau đó trong ctor mới cast IntPtr hoặc UIntPtr qua byte*.
Sorry mọi người, bug nằm ở đây, đáng ra phải là:
Compiler nó báo lỗi sai chỗ (nó lại báo lỗi ở outputArr) nên mình không nhận ra cái này.
Không biết mọi người thế nào, nhưng mình rất ngại dùng var. Bởi vì nó nhận nhiều loại biến nên nó rất khó bắt lỗi syntax. Không tóm được lỗi syntax thì rất dễ ăn lỗi runtime. Debug lỗi runtime nhọc lắm @@.